aboutsummaryrefslogtreecommitdiffstats
path: root/lib/inets/test
diff options
context:
space:
mode:
authorSverker Eriksson <[email protected]>2017-08-30 20:55:08 +0200
committerSverker Eriksson <[email protected]>2017-08-30 20:55:08 +0200
commit7c67bbddb53c364086f66260701bc54a61c9659c (patch)
tree92ab0d4b91d5e2f6e7a3f9d61ea25089e8a71fe0 /lib/inets/test
parent97dc5e7f396129222419811c173edc7fa767b0f8 (diff)
parent3b7a6ffddc819bf305353a593904cea9e932e7dc (diff)
downloadotp-7c67bbddb53c364086f66260701bc54a61c9659c.tar.gz
otp-7c67bbddb53c364086f66260701bc54a61c9659c.tar.bz2
otp-7c67bbddb53c364086f66260701bc54a61c9659c.zip
Merge tag 'OTP-19.0' into sverker/19/binary_to_atom-utf8-crash/ERL-474/OTP-14590
Diffstat (limited to 'lib/inets/test')
-rw-r--r--lib/inets/test/Makefile51
-rw-r--r--lib/inets/test/erl_make_certs.erl31
-rw-r--r--lib/inets/test/ftp_SUITE.erl1125
-rw-r--r--lib/inets/test/ftp_SUITE_data/vsftpd.conf26
-rw-r--r--lib/inets/test/ftp_format_SUITE.erl135
-rw-r--r--lib/inets/test/ftp_freebsd_x86_test.erl160
-rw-r--r--lib/inets/test/ftp_linux_ppc_test.erl158
-rw-r--r--lib/inets/test/ftp_linux_x86_test.erl160
-rw-r--r--lib/inets/test/ftp_macosx_ppc_test.erl159
-rw-r--r--lib/inets/test/ftp_macosx_x86_test.erl159
-rw-r--r--lib/inets/test/ftp_netbsd_x86_test.erl159
-rw-r--r--lib/inets/test/ftp_openbsd_x86_test.erl158
-rw-r--r--lib/inets/test/ftp_property_test_SUITE.erl53
-rw-r--r--lib/inets/test/ftp_solaris10_sparc_test.erl161
-rw-r--r--lib/inets/test/ftp_solaris10_x86_test.erl162
-rw-r--r--lib/inets/test/ftp_solaris8_sparc_test.erl159
-rw-r--r--lib/inets/test/ftp_solaris9_sparc_test.erl158
-rw-r--r--lib/inets/test/ftp_suite_lib.erl1675
-rw-r--r--lib/inets/test/ftp_ticket_test.erl61
-rw-r--r--lib/inets/test/ftp_windows_2003_server_test.erl167
-rw-r--r--lib/inets/test/ftp_windows_xp_test.erl157
-rw-r--r--lib/inets/test/http_format_SUITE.erl288
-rw-r--r--lib/inets/test/httpc_SUITE.erl442
-rw-r--r--lib/inets/test/httpc_SUITE_data/ssl_client_cert.pem45
-rw-r--r--lib/inets/test/httpc_SUITE_data/ssl_server_cert.pem45
-rw-r--r--lib/inets/test/httpc_cookie_SUITE.erl392
-rw-r--r--lib/inets/test/httpc_proxy_SUITE.erl78
-rw-r--r--lib/inets/test/httpc_proxy_SUITE_data/apache2/apache2.conf21
-rwxr-xr-xlib/inets/test/httpc_proxy_SUITE_data/server_proxy.sh23
-rw-r--r--lib/inets/test/httpd_1_0.erl39
-rw-r--r--lib/inets/test/httpd_1_1.erl203
-rw-r--r--lib/inets/test/httpd_SUITE.erl4117
-rw-r--r--lib/inets/test/httpd_SUITE_data/Makefile.src5
-rw-r--r--lib/inets/test/httpd_SUITE_data/mime_types.txt100
-rw-r--r--lib/inets/test/httpd_SUITE_data/server_root/config/mime.types4
-rw-r--r--lib/inets/test/httpd_SUITE_data/server_root/ssl/ssl_client.pem22
-rw-r--r--lib/inets/test/httpd_SUITE_data/server_root/ssl/ssl_server.pem22
-rw-r--r--lib/inets/test/httpd_all.erl240
-rw-r--r--lib/inets/test/httpd_basic_SUITE.erl395
-rw-r--r--lib/inets/test/httpd_basic_SUITE_data/Makefile.src14
-rw-r--r--lib/inets/test/httpd_basic_SUITE_data/cgi_sleep.c26
l---------lib/inets/test/httpd_basic_SUITE_data/printenv.bat1
l---------lib/inets/test/httpd_basic_SUITE_data/printenv.sh1
-rw-r--r--lib/inets/test/httpd_block.erl82
-rw-r--r--lib/inets/test/httpd_load.erl31
-rw-r--r--lib/inets/test/httpd_mod.erl220
-rw-r--r--lib/inets/test/httpd_mod_SUITE.erl77
-rw-r--r--lib/inets/test/httpd_poll.erl27
-rw-r--r--lib/inets/test/httpd_test_data/server_root/Makefile21
-rw-r--r--lib/inets/test/httpd_test_data/server_root/conf/8080.conf2
-rw-r--r--lib/inets/test/httpd_test_data/server_root/conf/8888.conf2
-rw-r--r--lib/inets/test/httpd_test_data/server_root/conf/httpd.conf25
-rw-r--r--lib/inets/test/httpd_test_data/server_root/conf/ssl.conf2
-rw-r--r--lib/inets/test/httpd_test_lib.erl193
-rw-r--r--lib/inets/test/httpd_time_test.erl90
-rw-r--r--lib/inets/test/inets_SUITE.erl318
-rw-r--r--lib/inets/test/inets_app_test.erl307
-rw-r--r--lib/inets/test/inets_appup_test.erl358
-rw-r--r--lib/inets/test/inets_socketwrap_SUITE.erl154
-rw-r--r--lib/inets/test/inets_socketwrap_SUITE_data/Makefile.src39
-rw-r--r--lib/inets/test/inets_socketwrap_SUITE_data/setuid_socket_wrap.c259
-rw-r--r--lib/inets/test/inets_sup_SUITE.erl432
-rw-r--r--lib/inets/test/inets_sup_SUITE_data/mime.types3
-rw-r--r--lib/inets/test/inets_sup_SUITE_data/simple.conf6
-rw-r--r--lib/inets/test/inets_test_lib.erl61
-rw-r--r--lib/inets/test/inets_test_lib.hrl109
-rw-r--r--lib/inets/test/old_httpd_SUITE.erl2347
-rw-r--r--lib/inets/test/old_httpd_SUITE_data/Makefile.src14
-rw-r--r--lib/inets/test/old_httpd_SUITE_data/cgi_echo.c97
-rw-r--r--lib/inets/test/old_httpd_SUITE_data/server_root/Makefile (renamed from lib/inets/test/httpd_SUITE_data/server_root/Makefile)21
-rw-r--r--lib/inets/test/old_httpd_SUITE_data/server_root/auth/group3
-rw-r--r--lib/inets/test/old_httpd_SUITE_data/server_root/auth/passwd4
-rw-r--r--lib/inets/test/old_httpd_SUITE_data/server_root/cgi-bin/printenv.bat9
-rwxr-xr-xlib/inets/test/old_httpd_SUITE_data/server_root/cgi-bin/printenv.sh6
-rw-r--r--lib/inets/test/old_httpd_SUITE_data/server_root/conf/8080.conf (renamed from lib/inets/test/httpd_SUITE_data/server_root/conf/8080.conf)2
-rw-r--r--lib/inets/test/old_httpd_SUITE_data/server_root/conf/8888.conf (renamed from lib/inets/test/httpd_SUITE_data/server_root/conf/8888.conf)2
-rw-r--r--lib/inets/test/old_httpd_SUITE_data/server_root/conf/httpd.conf (renamed from lib/inets/test/httpd_SUITE_data/server_root/conf/httpd.conf)25
-rw-r--r--lib/inets/test/old_httpd_SUITE_data/server_root/conf/mime.types (renamed from lib/inets/test/httpd_SUITE_data/server_root/conf/mime.types)0
-rw-r--r--lib/inets/test/old_httpd_SUITE_data/server_root/conf/ssl.conf (renamed from lib/inets/test/httpd_SUITE_data/server_root/conf/ssl.conf)2
-rw-r--r--lib/inets/test/old_httpd_SUITE_data/server_root/htdocs/config.shtml70
-rw-r--r--lib/inets/test/old_httpd_SUITE_data/server_root/htdocs/dets_open/dummy.html10
-rw-r--r--lib/inets/test/old_httpd_SUITE_data/server_root/htdocs/dets_secret/dummy.html10
-rw-r--r--lib/inets/test/old_httpd_SUITE_data/server_root/htdocs/dets_secret/top_secret/index.html9
-rw-r--r--lib/inets/test/old_httpd_SUITE_data/server_root/htdocs/echo.shtml35
-rw-r--r--lib/inets/test/old_httpd_SUITE_data/server_root/htdocs/exec.shtml30
-rw-r--r--lib/inets/test/old_httpd_SUITE_data/server_root/htdocs/flastmod.shtml29
-rw-r--r--lib/inets/test/old_httpd_SUITE_data/server_root/htdocs/fsize.shtml29
-rw-r--r--lib/inets/test/old_httpd_SUITE_data/server_root/htdocs/include.shtml33
-rw-r--r--lib/inets/test/old_httpd_SUITE_data/server_root/htdocs/index.html25
-rw-r--r--lib/inets/test/old_httpd_SUITE_data/server_root/htdocs/last_modified.html22
-rw-r--r--lib/inets/test/old_httpd_SUITE_data/server_root/htdocs/misc/friedrich.html7
-rw-r--r--lib/inets/test/old_httpd_SUITE_data/server_root/htdocs/misc/oech.html4
-rw-r--r--lib/inets/test/old_httpd_SUITE_data/server_root/htdocs/misc/welcome.html1
-rw-r--r--lib/inets/test/old_httpd_SUITE_data/server_root/htdocs/mnesia_open/dummy.html10
-rw-r--r--lib/inets/test/old_httpd_SUITE_data/server_root/htdocs/mnesia_secret/dummy.html10
-rw-r--r--lib/inets/test/old_httpd_SUITE_data/server_root/htdocs/mnesia_secret/top_secret/index.html9
-rw-r--r--lib/inets/test/old_httpd_SUITE_data/server_root/htdocs/open/dummy.html10
-rw-r--r--lib/inets/test/old_httpd_SUITE_data/server_root/htdocs/secret/dummy.html10
-rw-r--r--lib/inets/test/old_httpd_SUITE_data/server_root/htdocs/secret/top_secret/index.html9
-rw-r--r--lib/inets/test/old_httpd_SUITE_data/server_root/icons/README (renamed from lib/inets/test/httpd_SUITE_data/server_root/icons/README)0
-rw-r--r--lib/inets/test/old_httpd_SUITE_data/server_root/icons/a.gifbin0 -> 246 bytes
-rw-r--r--lib/inets/test/old_httpd_SUITE_data/server_root/icons/alert.black.gifbin0 -> 242 bytes
-rw-r--r--lib/inets/test/old_httpd_SUITE_data/server_root/icons/alert.red.gifbin0 -> 247 bytes
-rw-r--r--lib/inets/test/old_httpd_SUITE_data/server_root/icons/apache_pb.gifbin0 -> 2326 bytes
-rw-r--r--lib/inets/test/old_httpd_SUITE_data/server_root/icons/back.gifbin0 -> 216 bytes
-rw-r--r--lib/inets/test/old_httpd_SUITE_data/server_root/icons/ball.gray.gifbin0 -> 233 bytes
-rw-r--r--lib/inets/test/old_httpd_SUITE_data/server_root/icons/ball.red.gifbin0 -> 205 bytes
-rw-r--r--lib/inets/test/old_httpd_SUITE_data/server_root/icons/binary.gifbin0 -> 246 bytes
-rw-r--r--lib/inets/test/old_httpd_SUITE_data/server_root/icons/binhex.gifbin0 -> 246 bytes
-rw-r--r--lib/inets/test/old_httpd_SUITE_data/server_root/icons/blank.gifbin0 -> 148 bytes
-rw-r--r--lib/inets/test/old_httpd_SUITE_data/server_root/icons/bomb.gifbin0 -> 308 bytes
-rw-r--r--lib/inets/test/old_httpd_SUITE_data/server_root/icons/box1.gifbin0 -> 251 bytes
-rw-r--r--lib/inets/test/old_httpd_SUITE_data/server_root/icons/box2.gifbin0 -> 268 bytes
-rw-r--r--lib/inets/test/old_httpd_SUITE_data/server_root/icons/broken.gifbin0 -> 247 bytes
-rw-r--r--lib/inets/test/old_httpd_SUITE_data/server_root/icons/burst.gifbin0 -> 235 bytes
-rw-r--r--lib/inets/test/old_httpd_SUITE_data/server_root/icons/button1.gifbin0 -> 755 bytes
-rw-r--r--lib/inets/test/old_httpd_SUITE_data/server_root/icons/button10.gifbin0 -> 781 bytes
-rw-r--r--lib/inets/test/old_httpd_SUITE_data/server_root/icons/button2.gifbin0 -> 785 bytes
-rw-r--r--lib/inets/test/old_httpd_SUITE_data/server_root/icons/button3.gifbin0 -> 745 bytes
-rw-r--r--lib/inets/test/old_httpd_SUITE_data/server_root/icons/button4.gifbin0 -> 786 bytes
-rw-r--r--lib/inets/test/old_httpd_SUITE_data/server_root/icons/button5.gifbin0 -> 780 bytes
-rw-r--r--lib/inets/test/old_httpd_SUITE_data/server_root/icons/button6.gifbin0 -> 791 bytes
-rw-r--r--lib/inets/test/old_httpd_SUITE_data/server_root/icons/button7.gifbin0 -> 796 bytes
-rw-r--r--lib/inets/test/old_httpd_SUITE_data/server_root/icons/button8.gifbin0 -> 784 bytes
-rw-r--r--lib/inets/test/old_httpd_SUITE_data/server_root/icons/button9.gifbin0 -> 784 bytes
-rw-r--r--lib/inets/test/old_httpd_SUITE_data/server_root/icons/buttonl.gifbin0 -> 587 bytes
-rw-r--r--lib/inets/test/old_httpd_SUITE_data/server_root/icons/buttonr.gifbin0 -> 576 bytes
-rw-r--r--lib/inets/test/old_httpd_SUITE_data/server_root/icons/c.gifbin0 -> 242 bytes
-rw-r--r--lib/inets/test/old_httpd_SUITE_data/server_root/icons/comp.blue.gifbin0 -> 251 bytes
-rw-r--r--lib/inets/test/old_httpd_SUITE_data/server_root/icons/comp.gray.gifbin0 -> 246 bytes
-rw-r--r--lib/inets/test/old_httpd_SUITE_data/server_root/icons/compressed.gifbin0 -> 1038 bytes
-rw-r--r--lib/inets/test/old_httpd_SUITE_data/server_root/icons/continued.gifbin0 -> 214 bytes
-rw-r--r--lib/inets/test/old_httpd_SUITE_data/server_root/icons/dir.gifbin0 -> 225 bytes
-rw-r--r--lib/inets/test/old_httpd_SUITE_data/server_root/icons/down.gifbin0 -> 163 bytes
-rw-r--r--lib/inets/test/old_httpd_SUITE_data/server_root/icons/dvi.gifbin0 -> 238 bytes
-rw-r--r--lib/inets/test/old_httpd_SUITE_data/server_root/icons/f.gifbin0 -> 236 bytes
-rw-r--r--lib/inets/test/old_httpd_SUITE_data/server_root/icons/folder.gifbin0 -> 225 bytes
-rw-r--r--lib/inets/test/old_httpd_SUITE_data/server_root/icons/folder.open.gifbin0 -> 242 bytes
-rw-r--r--lib/inets/test/old_httpd_SUITE_data/server_root/icons/folder.sec.gifbin0 -> 243 bytes
-rw-r--r--lib/inets/test/old_httpd_SUITE_data/server_root/icons/forward.gifbin0 -> 219 bytes
-rw-r--r--lib/inets/test/old_httpd_SUITE_data/server_root/icons/generic.gifbin0 -> 221 bytes
-rw-r--r--lib/inets/test/old_httpd_SUITE_data/server_root/icons/generic.red.gifbin0 -> 220 bytes
-rw-r--r--lib/inets/test/old_httpd_SUITE_data/server_root/icons/generic.sec.gifbin0 -> 249 bytes
-rw-r--r--lib/inets/test/old_httpd_SUITE_data/server_root/icons/hand.right.gifbin0 -> 217 bytes
-rw-r--r--lib/inets/test/old_httpd_SUITE_data/server_root/icons/hand.up.gifbin0 -> 223 bytes
-rw-r--r--lib/inets/test/old_httpd_SUITE_data/server_root/icons/htdig.gifbin0 -> 1822 bytes
-rw-r--r--lib/inets/test/old_httpd_SUITE_data/server_root/icons/icon.sheet.gifbin0 -> 11977 bytes
-rw-r--r--lib/inets/test/old_httpd_SUITE_data/server_root/icons/image1.gifbin0 -> 274 bytes
-rw-r--r--lib/inets/test/old_httpd_SUITE_data/server_root/icons/image2.gifbin0 -> 309 bytes
-rw-r--r--lib/inets/test/old_httpd_SUITE_data/server_root/icons/image3.gifbin0 -> 286 bytes
-rw-r--r--lib/inets/test/old_httpd_SUITE_data/server_root/icons/index.gifbin0 -> 268 bytes
-rw-r--r--lib/inets/test/old_httpd_SUITE_data/server_root/icons/layout.gifbin0 -> 276 bytes
-rw-r--r--lib/inets/test/old_httpd_SUITE_data/server_root/icons/left.gifbin0 -> 172 bytes
-rw-r--r--lib/inets/test/old_httpd_SUITE_data/server_root/icons/link.gifbin0 -> 249 bytes
-rw-r--r--lib/inets/test/old_httpd_SUITE_data/server_root/icons/movie.gifbin0 -> 243 bytes
-rw-r--r--lib/inets/test/old_httpd_SUITE_data/server_root/icons/p.gifbin0 -> 237 bytes
-rw-r--r--lib/inets/test/old_httpd_SUITE_data/server_root/icons/patch.gifbin0 -> 251 bytes
-rw-r--r--lib/inets/test/old_httpd_SUITE_data/server_root/icons/pdf.gifbin0 -> 249 bytes
-rw-r--r--lib/inets/test/old_httpd_SUITE_data/server_root/icons/pie0.gifbin0 -> 188 bytes
-rw-r--r--lib/inets/test/old_httpd_SUITE_data/server_root/icons/pie1.gifbin0 -> 198 bytes
-rw-r--r--lib/inets/test/old_httpd_SUITE_data/server_root/icons/pie2.gifbin0 -> 198 bytes
-rw-r--r--lib/inets/test/old_httpd_SUITE_data/server_root/icons/pie3.gifbin0 -> 191 bytes
-rw-r--r--lib/inets/test/old_httpd_SUITE_data/server_root/icons/pie4.gifbin0 -> 193 bytes
-rw-r--r--lib/inets/test/old_httpd_SUITE_data/server_root/icons/pie5.gifbin0 -> 189 bytes
-rw-r--r--lib/inets/test/old_httpd_SUITE_data/server_root/icons/pie6.gifbin0 -> 186 bytes
-rw-r--r--lib/inets/test/old_httpd_SUITE_data/server_root/icons/pie7.gifbin0 -> 185 bytes
-rw-r--r--lib/inets/test/old_httpd_SUITE_data/server_root/icons/pie8.gifbin0 -> 173 bytes
-rw-r--r--lib/inets/test/old_httpd_SUITE_data/server_root/icons/portal.gifbin0 -> 254 bytes
-rw-r--r--lib/inets/test/old_httpd_SUITE_data/server_root/icons/poweredby.gifbin0 -> 2748 bytes
-rw-r--r--lib/inets/test/old_httpd_SUITE_data/server_root/icons/ps.gifbin0 -> 244 bytes
-rw-r--r--lib/inets/test/old_httpd_SUITE_data/server_root/icons/quill.gifbin0 -> 267 bytes
-rw-r--r--lib/inets/test/old_httpd_SUITE_data/server_root/icons/right.gifbin0 -> 172 bytes
-rw-r--r--lib/inets/test/old_httpd_SUITE_data/server_root/icons/screw1.gifbin0 -> 258 bytes
-rw-r--r--lib/inets/test/old_httpd_SUITE_data/server_root/icons/screw2.gifbin0 -> 263 bytes
-rw-r--r--lib/inets/test/old_httpd_SUITE_data/server_root/icons/script.gifbin0 -> 242 bytes
-rw-r--r--lib/inets/test/old_httpd_SUITE_data/server_root/icons/sound1.gifbin0 -> 248 bytes
-rw-r--r--lib/inets/test/old_httpd_SUITE_data/server_root/icons/sound2.gifbin0 -> 221 bytes
-rw-r--r--lib/inets/test/old_httpd_SUITE_data/server_root/icons/sphere1.gifbin0 -> 285 bytes
-rw-r--r--lib/inets/test/old_httpd_SUITE_data/server_root/icons/sphere2.gifbin0 -> 264 bytes
-rw-r--r--lib/inets/test/old_httpd_SUITE_data/server_root/icons/star.gifbin0 -> 89 bytes
-rw-r--r--lib/inets/test/old_httpd_SUITE_data/server_root/icons/star_blank.gifbin0 -> 53 bytes
-rw-r--r--lib/inets/test/old_httpd_SUITE_data/server_root/icons/tar.gifbin0 -> 243 bytes
-rw-r--r--lib/inets/test/old_httpd_SUITE_data/server_root/icons/tex.gifbin0 -> 251 bytes
-rw-r--r--lib/inets/test/old_httpd_SUITE_data/server_root/icons/text.gifbin0 -> 229 bytes
-rw-r--r--lib/inets/test/old_httpd_SUITE_data/server_root/icons/transfer.gifbin0 -> 242 bytes
-rw-r--r--lib/inets/test/old_httpd_SUITE_data/server_root/icons/unknown.gifbin0 -> 245 bytes
-rw-r--r--lib/inets/test/old_httpd_SUITE_data/server_root/icons/up.gifbin0 -> 164 bytes
-rw-r--r--lib/inets/test/old_httpd_SUITE_data/server_root/icons/uu.gifbin0 -> 236 bytes
-rw-r--r--lib/inets/test/old_httpd_SUITE_data/server_root/icons/uuencoded.gifbin0 -> 236 bytes
-rw-r--r--lib/inets/test/old_httpd_SUITE_data/server_root/icons/world1.gifbin0 -> 228 bytes
-rw-r--r--lib/inets/test/old_httpd_SUITE_data/server_root/icons/world2.gifbin0 -> 261 bytes
-rw-r--r--lib/inets/test/old_httpd_SUITE_data/server_root/logs/Dummy_File_Needed_By_WinZip (renamed from lib/inets/test/httpd_SUITE_data/server_root/logs/Dummy_File_Needed_By_WinZip)0
-rw-r--r--lib/inets/test/old_httpd_SUITE_data/server_root/ssl/ssl_client.pem31
-rw-r--r--lib/inets/test/old_httpd_SUITE_data/server_root/ssl/ssl_server.pem31
-rw-r--r--lib/inets/test/property_test/README12
-rw-r--r--lib/inets/test/property_test/ftp_simple_client_server.erl307
-rw-r--r--lib/inets/test/property_test/ftp_simple_client_server_data/vsftpd.conf26
-rw-r--r--lib/inets/test/tftp_SUITE.erl60
-rw-r--r--lib/inets/test/tftp_test_lib.erl23
-rw-r--r--lib/inets/test/tftp_test_lib.hrl23
-rw-r--r--lib/inets/test/uri_SUITE.erl81
201 files changed, 9179 insertions, 8894 deletions
diff --git a/lib/inets/test/Makefile b/lib/inets/test/Makefile
index dfa86906fd..ffc512050a 100644
--- a/lib/inets/test/Makefile
+++ b/lib/inets/test/Makefile
@@ -1,18 +1,19 @@
#
# %CopyrightBegin%
#
-# Copyright Ericsson AB 1997-2013. All Rights Reserved.
+# Copyright Ericsson AB 1997-2016. 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/.
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
#
-# 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.
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
#
# %CopyrightEnd%
#
@@ -41,7 +42,6 @@ RELSYSDIR = $(RELEASE_PATH)/lib/$(APPLICATION)-$(VSN)
# Target Specs
# ----------------------------------------------------
INCLUDES = -I. \
- -I$(ERL_TOP)/lib/test_server/include/ \
-I$(ERL_TOP)/lib/inets/src/inets_app \
-I$(ERL_TOP)/lib/inets/src/http_lib \
-I$(ERL_TOP)/lib/inets/src/http_client \
@@ -152,40 +152,26 @@ MODULES = \
erl_make_certs \
ftp_SUITE \
ftp_format_SUITE \
- ftp_solaris8_sparc_test \
- ftp_solaris9_sparc_test \
- ftp_solaris10_sparc_test \
- ftp_solaris10_x86_test \
- ftp_linux_x86_test \
- ftp_linux_ppc_test \
- ftp_macosx_x86_test \
- ftp_macosx_ppc_test \
- ftp_openbsd_x86_test \
- ftp_freebsd_x86_test \
- ftp_netbsd_x86_test \
- ftp_windows_xp_test \
- ftp_windows_2003_server_test \
- ftp_suite_lib \
- ftp_ticket_test \
http_format_SUITE \
httpc_SUITE \
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 \
- inets_app_test \
- inets_appup_test \
tftp_test_lib \
tftp_SUITE \
- uri_SUITE
+ uri_SUITE \
+ inets_socketwrap_SUITE
EBIN = .
@@ -214,8 +200,8 @@ INETS_FILES = inets.config $(INETS_SPECS)
# inets_ftp_suite \
# inets_tftp_suite
-INETS_DATADIRS = inets_SUITE_data inets_sup_SUITE_data
-HTTPD_DATADIRS = httpd_test_data httpd_SUITE_data
+INETS_DATADIRS = inets_SUITE_data inets_socketwrap_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
@@ -248,7 +234,6 @@ RELTESTSYSBINDIR = $(RELTESTSYSALLDATADIR)/bin
# running the target "targets".
# ----------------------------------------------------
ERL_COMPILE_FLAGS += \
- -pa ../../../internal_tools/test_server/ebin \
$(INCLUDES) \
$(FTP_FLAGS) \
$(INETS_FLAGS)
@@ -261,7 +246,7 @@ ERL_COMPILE_FLAGS += \
# 1) INETS_PRIV_DIR must be created
# ----------------------------------------------------
-tests debug opt: $(BUILDTARGET)
+tests debug opt: $(BUILDTARGET)
targets: $(TARGET_FILES)
diff --git a/lib/inets/test/erl_make_certs.erl b/lib/inets/test/erl_make_certs.erl
index 22dc951ac1..2db95825bc 100644
--- a/lib/inets/test/erl_make_certs.erl
+++ b/lib/inets/test/erl_make_certs.erl
@@ -1,18 +1,19 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2011-2013. All Rights Reserved.
+%% Copyright Ericsson AB 2011-2016. 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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% 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.
+%% http://www.apache.org/licenses/LICENSE-2.0
+%%
+%% Unless required by applicable law or agreed to in writing, software
+%% distributed under the License is distributed on an "AS IS" BASIS,
+%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+%% See the License for the specific language governing permissions and
+%% limitations under the License.
%%
%% %CopyrightEnd%
%%
@@ -204,7 +205,7 @@ issuer_der(Issuer) ->
Subject.
subject(undefined, IsRootCA) ->
- User = if IsRootCA -> "RootCA"; true -> user() end,
+ User = if IsRootCA -> "RootCA"; true -> os:getenv("USER", "test_user") end,
Opts = [{email, User ++ "@erlang.org"},
{name, User},
{city, "Stockholm"},
@@ -215,14 +216,6 @@ subject(undefined, IsRootCA) ->
subject(Opts, _) ->
subject(Opts).
-user() ->
- case os:getenv("USER") of
- false ->
- "test_user";
- User ->
- User
- end.
-
subject(SubjectOpts) when is_list(SubjectOpts) ->
Encode = fun(Opt) ->
{Type,Value} = subject_enc(Opt),
diff --git a/lib/inets/test/ftp_SUITE.erl b/lib/inets/test/ftp_SUITE.erl
index 17e5f6777e..e2dec0c42a 100644
--- a/lib/inets/test/ftp_SUITE.erl
+++ b/lib/inets/test/ftp_SUITE.erl
@@ -1,127 +1,1080 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2005-2011. All Rights Reserved.
+%% Copyright Ericsson AB 2004-2016. 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.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
+%%
+%% http://www.apache.org/licenses/LICENSE-2.0
+%%
+%% Unless required by applicable law or agreed to in writing, software
+%% distributed under the License is distributed on an "AS IS" BASIS,
+%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+%% See the License for the specific language governing permissions and
+%% limitations under the License.
%%
%% %CopyrightEnd%
%%
%%
+%%
+%% ct:run("../inets_test", ftp_SUITE).
+%%
+
-module(ftp_SUITE).
+-include_lib("kernel/include/file.hrl").
-include_lib("common_test/include/ct.hrl").
--include("test_server_line.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]).
--export([init_per_suite/1, end_per_suite/1]).
+%% Note: This directive should only be used in test suites.
+-compile(export_all).
-define(FTP_USER, "anonymous").
--define(FTP_PASS, passwd()).
--define(FTP_PORT, 21).
+-define(FTP_PASS(Cmnt), (fun({ok,__H}) -> "ftp_SUITE_"++Cmnt++"@" ++ __H;
+ (_) -> "ftp_SUITE_"++Cmnt++"@localhost"
+ end)(inet:gethostname())
+ ).
-define(BAD_HOST, "badhostname").
-define(BAD_USER, "baduser").
-define(BAD_DIR, "baddirectory").
--ifdef(ftp_debug_client).
--define(ftp_open(Host, Flags), do_ftp_open(Host, [debug] ++ Flags)).
--else.
--ifdef(ftp_trace_client).
--define(ftp_open(Host, Flags), do_ftp_open(Host, [trace] ++ Flags)).
--else.
--define(ftp_open(Host, Flags), do_ftp_open(Host, [verbose] ++ Flags)).
--endif.
--endif.
-
+-record(progress, {
+ current = 0,
+ total
+ }).
%%--------------------------------------------------------------------
-%% 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() ->
+ [{timetrap,{seconds,20}}].
+
+all() ->
+ [
+ {group, ftp_passive},
+ {group, ftp_active},
+ {group, ftps_passive},
+ {group, ftps_active},
+ error_ehost,
+ clean_shutdown
+ ].
-all() ->
+groups() ->
[
- {group, solaris8_test},
- {group, solaris9_test},
- {group, solaris10_test},
- {group, linux_x86_test},
- {group, linux_ppc_test},
- {group, macosx_x86_test},
- {group, macosx_ppc_test},
- {group, openbsd_test},
- {group, freebsd_test},
- {group, netbsd_test},
- {group, windows_xp_test},
- {group, windows_2003_server_test},
- {group, ticket_tests}
+ {ftp_passive, [], ftp_tests()},
+ {ftp_active, [], ftp_tests()},
+ {ftps_passive, [], ftp_tests()},
+ {ftps_active, [], ftp_tests()}
].
-groups() ->
+ftp_tests()->
[
- {solaris8_test, [], [{ftp_solaris8_sparc_test, all}]},
- {solaris9_test, [], [{ftp_solaris9_sparc_test, all}]},
- {solaris10_test, [], [{ftp_solaris10_sparc_test, all},
- {ftp_solaris10_x86_test, all}]},
- {linux_x86_test, [], [{ftp_linux_x86_test, all}]},
- {linux_ppc_test, [], [{ftp_linux_ppc_test, all}]},
- {macosx_x86_test, [], [{ftp_macosx_x86_test, all}]},
- {macosx_ppc_test, [], [{ftp_macosx_ppc_test, all}]},
- {openbsd_test, [], [{ftp_openbsd_x86_test, all}]},
- {freebsd_test, [], [{ftp_freebsd_x86_test, all}]},
- {netbsd_test, [], [{ftp_netbsd_x86_test, all}]},
- {windows_xp_test, [], [{ftp_windows_xp_test, all}]},
- {windows_2003_server_test, [], [{ftp_windows_2003_server_test, all}]},
- {ticket_tests, [], [{ftp_ticket_test, all}]}
+ user,
+ bad_user,
+ pwd,
+ cd,
+ lcd,
+ ls,
+ nlist,
+ rename,
+ delete,
+ mkdir,
+ rmdir,
+ send,
+ send_3,
+ send_bin,
+ send_chunk,
+ append,
+ append_bin,
+ append_chunk,
+ recv,
+ recv_3,
+ recv_bin,
+ recv_chunk,
+ type,
+ quote,
+ error_elogin,
+ progress_report_send,
+ progress_report_recv,
+ not_owner,
+ unexpected_call,
+ unexpected_cast,
+ unexpected_bang
].
-init_per_group(_GroupName, Config) ->
- Config.
+%%--------------------------------------------------------------------
-end_per_group(_GroupName, Config) ->
- Config.
+%%% Config
+%%% key meaning
+%%% ................................................................
+%%% ftpservers list of servers to check if they are available
+%%% The element is:
+%%% {Name, % string(). The os command name
+%%% Path, % string(). The os PATH syntax, e.g "/bin:/usr/bin"
+%%% StartCommand, % fun()->{ok,start_result()} | {error,string()}.
+%%% % The command to start the daemon with.
+%%% ChkUp, % fun(start_result()) -> string(). Os command to check
+%%% % if the server is running. [] if not running.
+%%% % The string in string() is suitable for logging.
+%%% StopCommand, % fun(start_result()) -> void(). The command to stop the daemon with.
+%%% AugmentFun, % fun(config()) -> config() Adds two funs for transforming names of files
+%%% % and directories to the form they are returned from this server
+%%% ServerHost, % string(). Mostly "localhost"
+%%% ServerPort % pos_integer()
+%%% }
+%%%
+-define(default_ftp_servers,
+ [{"vsftpd",
+ "/sbin:/usr/sbin:/usr/local/sbin",
+ fun(__CONF__, AbsName) ->
+ DataDir = proplists:get_value(data_dir,__CONF__),
+ ConfFile = filename:join(DataDir, "vsftpd.conf"),
+ PrivDir = proplists:get_value(priv_dir,__CONF__),
+ AnonRoot = PrivDir,
+ Cmd = [AbsName ++" "++filename:join(DataDir,"vsftpd.conf"),
+ " -oftpd_banner=erlang_otp_testing",
+ " -oanon_root=\"",AnonRoot,"\"",
+ " -orsa_cert_file=\"",filename:join(DataDir,"server-cert.pem"),"\"",
+ " -orsa_private_key_file=\"",filename:join(DataDir,"server-key.pem"),"\""
+ ],
+ Result = os:cmd(Cmd),
+ ct:log("Config file:~n~s~n~nServer start command:~n ~s~nResult:~n ~p",
+ [case file:read_file(ConfFile) of
+ {ok,X} -> X;
+ _ -> ""
+ end,
+ Cmd, Result
+ ]),
+ case Result of
+ [] -> {ok,'dont care'};
+ [Msg] -> {error,Msg}
+ end
+ end,
+ fun(_StartResult) -> os:cmd("ps ax | grep erlang_otp_testing | grep -v grep")
+ end,
+ fun(_StartResult) -> os:cmd("kill `ps ax | grep erlang_otp_testing | awk '/vsftpd/{print $1}'`")
+ end,
+ fun(__CONF__) ->
+ AnonRoot = proplists:get_value(priv_dir,__CONF__),
+ [{id2ftp, fun(Id) -> filename:join(AnonRoot,Id) end},
+ {id2ftp_result,fun(Id) -> filename:join(AnonRoot,Id) end} | __CONF__]
+ end,
+ "localhost",
+ 9999
+ }
+ ]
+ ).
+init_per_suite(Config) ->
+ case find_executable(Config) of
+ false ->
+ {skip, "No ftp server found"};
+ {ok,Data} ->
+ TstDir = filename:join(proplists:get_value(priv_dir,Config), "test"),
+ file:make_dir(TstDir),
+ make_cert_files(dsa, rsa, "server-", proplists:get_value(data_dir,Config)),
+ start_ftpd([{test_dir,TstDir},
+ {ftpd_data,Data}
+ | Config])
+ end.
+
+end_per_suite(Config) ->
+ ps_ftpd(Config),
+ stop_ftpd(Config),
+ ps_ftpd(Config),
+ ok.
%%--------------------------------------------------------------------
-%% 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_group(_Group, Config) -> Config.
+
+end_per_group(_Group, Config) -> Config.
+
%%--------------------------------------------------------------------
-init_per_suite(Config) ->
- inets:start(),
- Config.
+init_per_testcase(Case, Config0) ->
+ Group = proplists:get_value(name, proplists:get_value(tc_group_properties,Config0)),
+ TLS = [{tls,[{reuse_sessions,true}]}],
+ ACTIVE = [{mode,active}],
+ PASSIVE = [{mode,passive}],
+ CaseOpts = case Case of
+ progress_report_send -> [{progress, {?MODULE,progress,#progress{}}}];
+ progress_report_recv -> [{progress, {?MODULE,progress,#progress{}}}];
+ _ -> []
+ end,
+ ExtraOpts = [verbose | CaseOpts],
+ Config =
+ case Group of
+ ftp_active -> ftp__open(Config0, ACTIVE ++ ExtraOpts);
+ ftps_active -> ftp__open(Config0, TLS++ ACTIVE ++ ExtraOpts);
+ ftp_passive -> ftp__open(Config0, PASSIVE ++ ExtraOpts);
+ ftps_passive -> ftp__open(Config0, TLS++PASSIVE ++ ExtraOpts);
+ undefined -> Config0
+ end,
+ case Case of
+ user -> Config;
+ bad_user -> Config;
+ error_elogin -> Config;
+ error_ehost -> Config;
+ clean_shutdown -> Config;
+ _ ->
+ Pid = proplists:get_value(ftp,Config),
+ ok = ftp:user(Pid, ?FTP_USER, ?FTP_PASS(atom_to_list(Group)++"-"++atom_to_list(Case)) ),
+ ok = ftp:cd(Pid, proplists:get_value(priv_dir,Config)),
+ Config
+ end.
+
+
+end_per_testcase(user, _Config) -> ok;
+end_per_testcase(bad_user, _Config) -> ok;
+end_per_testcase(error_elogin, _Config) -> ok;
+end_per_testcase(error_ehost, _Config) -> ok;
+end_per_testcase(clean_shutdown, _Config) -> ok;
+end_per_testcase(_Case, Config) ->
+ case proplists:get_value(tc_status,Config) of
+ ok -> ok;
+ _ ->
+ try ftp:latest_ctrl_response(proplists:get_value(ftp,Config))
+ of
+ {ok,S} -> ct:log("***~n*** Latest ctrl channel response:~n*** ~p~n***",[S])
+ catch
+ _:_ -> ok
+ end
+ end,
+ ftp__close(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
+%% Test Cases --------------------------------------------------------
%%--------------------------------------------------------------------
-end_per_suite(_Config) ->
- inets:stop(),
+user() -> [
+ {doc, "Open an ftp connection to a host, and logon as anonymous ftp,"
+ " then logoff"}].
+user(Config) ->
+ Pid = proplists:get_value(ftp, Config),
+ ok = ftp:user(Pid, ?FTP_USER, ?FTP_PASS("")),% logon
+ ok = ftp:close(Pid), % logoff
+ {error,eclosed} = ftp:pwd(Pid), % check logoff result
+ ok.
+
+%%-------------------------------------------------------------------------
+bad_user() ->
+ [{doc, "Open an ftp connection to a host, and logon with bad user."}].
+bad_user(Config) ->
+ Pid = proplists:get_value(ftp, Config),
+ {error, euser} = ftp:user(Pid, ?BAD_USER, ?FTP_PASS("")),
+ ok.
+
+%%-------------------------------------------------------------------------
+pwd() ->
+ [{doc, "Test ftp:pwd/1 & ftp:lpwd/1"}].
+pwd(Config0) ->
+ Config = set_state([reset], Config0),
+ Pid = proplists:get_value(ftp, Config),
+ {ok, PWD} = ftp:pwd(Pid),
+ {ok, PathLpwd} = ftp:lpwd(Pid),
+ PWD = id2ftp_result("", Config),
+ PathLpwd = id2ftp_result("", Config).
+
+%%-------------------------------------------------------------------------
+cd() ->
+ ["Open an ftp connection, log on as anonymous ftp, and cd to a"
+ "directory and to a non-existent directory."].
+cd(Config0) ->
+ Dir = "test",
+ Config = set_state([reset,{mkdir,Dir}], Config0),
+ Pid = proplists:get_value(ftp, Config),
+ ok = ftp:cd(Pid, id2ftp(Dir,Config)),
+ {ok, PWD} = ftp:pwd(Pid),
+ ExpectedPWD = id2ftp_result(Dir, Config),
+ PWD = ExpectedPWD,
+ {error, epath} = ftp:cd(Pid, ?BAD_DIR),
+ ok.
+
+%%-------------------------------------------------------------------------
+lcd() ->
+ [{doc, "Test api function ftp:lcd/2"}].
+lcd(Config0) ->
+ Dir = "test",
+ Config = set_state([reset,{mkdir,Dir}], Config0),
+ Pid = proplists:get_value(ftp, Config),
+ ok = ftp:lcd(Pid, id2ftp(Dir,Config)),
+ {ok, PWD} = ftp:lpwd(Pid),
+ ExpectedPWD = id2ftp_result(Dir, Config),
+ PWD = ExpectedPWD,
+ {error, epath} = ftp:lcd(Pid, ?BAD_DIR).
+
+%%-------------------------------------------------------------------------
+ls() ->
+ [{doc, "Open an ftp connection; ls the current directory, and the "
+ "\"test\" directory. We assume that ls never fails, since "
+ "it's output is meant to be read by humans. "}].
+ls(Config0) ->
+ Config = set_state([reset,{mkdir,"test"}], Config0),
+ Pid = proplists:get_value(ftp, Config),
+ {ok, _R1} = ftp:ls(Pid),
+ {ok, _R2} = ftp:ls(Pid, id2ftp("test",Config)),
+ %% neither nlist nor ls operates on a directory
+ %% they operate on a pathname, which *can* be a
+ %% directory, but can also be a filename or a group
+ %% of files (including wildcards).
+ case proplists:get_value(wildcard_support, Config) of
+ true ->
+ {ok, _R3} = ftp:ls(Pid, id2ftp("te*",Config));
+ _ ->
+ ok
+ end.
+
+%%-------------------------------------------------------------------------
+nlist() ->
+ [{doc,"Open an ftp connection; nlist the current directory, and the "
+ "\"test\" directory. Nlist does not behave consistenly over "
+ "operating systems. On some it is an error to have an empty "
+ "directory."}].
+nlist(Config0) ->
+ Config = set_state([reset,{mkdir,"test"}], Config0),
+ Pid = proplists:get_value(ftp, Config),
+ {ok, _R1} = ftp:nlist(Pid),
+ {ok, _R2} = ftp:nlist(Pid, id2ftp("test",Config)),
+ %% neither nlist nor ls operates on a directory
+ %% they operate on a pathname, which *can* be a
+ %% directory, but can also be a filename or a group
+ %% of files (including wildcards).
+ case proplists:get_value(wildcard_support, Config) of
+ true ->
+ {ok, _R3} = ftp:nlist(Pid, id2ftp("te*",Config));
+ _ ->
+ ok
+ end.
+
+%%-------------------------------------------------------------------------
+rename() ->
+ [{doc, "Rename a file."}].
+rename(Config0) ->
+ Contents = <<"ftp_SUITE test ...">>,
+ OldFile = "old.txt",
+ NewFile = "new.txt",
+ Config = set_state([reset,{mkfile,OldFile,Contents}], Config0),
+ Pid = proplists:get_value(ftp, Config),
+
+ ok = ftp:rename(Pid,
+ id2ftp(OldFile,Config),
+ id2ftp(NewFile,Config)),
+
+ true = (chk_file(NewFile,Contents,Config)
+ and chk_no_file([OldFile],Config)),
+ {error,epath} = ftp:rename(Pid,
+ id2ftp("non_existing_file",Config),
+ id2ftp(NewFile,Config)),
+ ok.
+
+%%-------------------------------------------------------------------------
+send() ->
+ [{doc, "Transfer a file with ftp using send/2."}].
+send(Config0) ->
+ Contents = <<"ftp_SUITE test ...">>,
+ SrcDir = "data",
+ File = "file.txt",
+ Config = set_state([reset,{mkfile,[SrcDir,File],Contents}], Config0),
+ Pid = proplists:get_value(ftp, Config),
+
+ chk_no_file([File],Config),
+ chk_file([SrcDir,File],Contents,Config),
+
+ ok = ftp:lcd(Pid, id2ftp(SrcDir,Config)),
+ ok = ftp:cd(Pid, id2ftp("",Config)),
+ ok = ftp:send(Pid, File),
+ chk_file(File, Contents, Config),
+
+ {error,epath} = ftp:send(Pid, "non_existing_file"),
ok.
+
+%%-------------------------------------------------------------------------
+send_3() ->
+ [{doc, "Transfer a file with ftp using send/3."}].
+send_3(Config0) ->
+ Contents = <<"ftp_SUITE test ...">>,
+ Dir = "incoming",
+ File = "file.txt",
+ RemoteFile = "remfile.txt",
+ Config = set_state([reset,{mkfile,File,Contents},{mkdir,Dir}], Config0),
+ Pid = proplists:get_value(ftp, Config),
+
+ ok = ftp:cd(Pid, id2ftp(Dir,Config)),
+ ok = ftp:lcd(Pid, id2ftp("",Config)),
+ ok = ftp:send(Pid, File, RemoteFile),
+ chk_file([Dir,RemoteFile], Contents, Config),
+
+ {error,epath} = ftp:send(Pid, "non_existing_file", RemoteFile),
+ ok.
+
+%%-------------------------------------------------------------------------
+send_bin() ->
+ [{doc, "Send a binary."}].
+send_bin(Config0) ->
+ BinContents = <<"ftp_SUITE test ...">>,
+ File = "file.txt",
+ Config = set_state([reset], Config0),
+ Pid = proplists:get_value(ftp, Config),
+ {error, enotbinary} = ftp:send_bin(Pid, "some string", id2ftp(File,Config)),
+ ok = ftp:send_bin(Pid, BinContents, id2ftp(File,Config)),
+ chk_file(File, BinContents, Config),
+ {error, efnamena} = ftp:send_bin(Pid, BinContents, "/nothere"),
+ ok.
+
+%%-------------------------------------------------------------------------
+send_chunk() ->
+ [{doc, "Send a binary using chunks."}].
+send_chunk(Config0) ->
+ Contents1 = <<"1: ftp_SUITE test ...">>,
+ Contents2 = <<"2: ftp_SUITE test ...">>,
+ File = "file.txt",
+ Config = set_state([reset,{mkdir,"incoming"}], Config0),
+ Pid = proplists:get_value(ftp, Config),
+
+ ok = ftp:send_chunk_start(Pid, id2ftp(File,Config)),
+ {error, echunk} = ftp:send_chunk_start(Pid, id2ftp(File,Config)),
+ {error, echunk} = ftp:cd(Pid, "incoming"),
+ {error, enotbinary} = ftp:send_chunk(Pid, "some string"),
+ ok = ftp:send_chunk(Pid, Contents1),
+ ok = ftp:send_chunk(Pid, Contents2),
+ ok = ftp:send_chunk_end(Pid),
+ chk_file(File, <<Contents1/binary,Contents2/binary>>, Config),
+
+ {error, echunk} = ftp:send_chunk(Pid, Contents1),
+ {error, echunk} = ftp:send_chunk_end(Pid),
+ {error, efnamena} = ftp:send_chunk_start(Pid, "/"),
+ ok.
+
+%%-------------------------------------------------------------------------
+delete() ->
+ [{doc, "Delete a file."}].
+delete(Config0) ->
+ Contents = <<"ftp_SUITE test ...">>,
+ File = "file.txt",
+ Config = set_state([reset,{mkfile,File,Contents}], Config0),
+ Pid = proplists:get_value(ftp, Config),
+ ok = ftp:delete(Pid, id2ftp(File,Config)),
+ chk_no_file([File], Config),
+ {error,epath} = ftp:delete(Pid, id2ftp(File,Config)),
+ ok.
+
+%%-------------------------------------------------------------------------
+mkdir() ->
+ [{doc, "Make a remote directory."}].
+mkdir(Config0) ->
+ NewDir = "new_dir",
+ Config = set_state([reset], Config0),
+ Pid = proplists:get_value(ftp, Config),
+ ok = ftp:mkdir(Pid, id2ftp(NewDir,Config)),
+ chk_dir([NewDir], Config),
+ {error,epath} = ftp:mkdir(Pid, id2ftp(NewDir,Config)),
+ ok.
+
+%%-------------------------------------------------------------------------
+rmdir() ->
+ [{doc, "Remove a directory."}].
+rmdir(Config0) ->
+ Dir = "dir",
+ Config = set_state([reset,{mkdir,Dir}], Config0),
+ Pid = proplists:get_value(ftp, Config),
+ ok = ftp:rmdir(Pid, id2ftp(Dir,Config)),
+ chk_no_dir([Dir], Config),
+ {error,epath} = ftp:rmdir(Pid, id2ftp(Dir,Config)),
+ ok.
+
+%%-------------------------------------------------------------------------
+append() ->
+ [{doc, "Append a local file twice to a remote file"}].
+append(Config0) ->
+ SrcFile = "f_src.txt",
+ DstFile = "f_dst.txt",
+ Contents = <<"ftp_SUITE test ...">>,
+ Config = set_state([reset,{mkfile,SrcFile,Contents}], Config0),
+ Pid = proplists:get_value(ftp, Config),
+ ok = ftp:append(Pid, id2ftp(SrcFile,Config), id2ftp(DstFile,Config)),
+ ok = ftp:append(Pid, id2ftp(SrcFile,Config), id2ftp(DstFile,Config)),
+ chk_file(DstFile, <<Contents/binary,Contents/binary>>, Config),
+ {error,epath} = ftp:append(Pid, id2ftp("non_existing_file",Config), id2ftp(DstFile,Config)),
+ ok.
+
+%%-------------------------------------------------------------------------
+append_bin() ->
+ [{doc, "Append a local file twice to a remote file using append_bin"}].
+append_bin(Config0) ->
+ DstFile = "f_dst.txt",
+ Contents = <<"ftp_SUITE test ...">>,
+ Config = set_state([reset], Config0),
+ Pid = proplists:get_value(ftp, Config),
+ ok = ftp:append_bin(Pid, Contents, id2ftp(DstFile,Config)),
+ ok = ftp:append_bin(Pid, Contents, id2ftp(DstFile,Config)),
+ chk_file(DstFile, <<Contents/binary,Contents/binary>>, Config).
+
+%%-------------------------------------------------------------------------
+append_chunk() ->
+ [{doc, "Append chunks."}].
+append_chunk(Config0) ->
+ File = "f_dst.txt",
+ Contents = [<<"ER">>,<<"LE">>,<<"RL">>],
+ Config = set_state([reset], Config0),
+ Pid = proplists:get_value(ftp, Config),
+ ok = ftp:append_chunk_start(Pid, id2ftp(File,Config)),
+ {error, enotbinary} = ftp:append_chunk(Pid, binary_to_list(lists:nth(1,Contents))),
+ ok = ftp:append_chunk(Pid,lists:nth(1,Contents)),
+ ok = ftp:append_chunk(Pid,lists:nth(2,Contents)),
+ ok = ftp:append_chunk(Pid,lists:nth(3,Contents)),
+ ok = ftp:append_chunk_end(Pid),
+ chk_file(File, <<"ERLERL">>, Config).
+
+%%-------------------------------------------------------------------------
+recv() ->
+ [{doc, "Receive a file using recv/2"}].
+recv(Config0) ->
+ File = "f_dst.txt",
+ SrcDir = "a_dir",
+ Contents = <<"ftp_SUITE test ...">>,
+ Config = set_state([reset, {mkfile,[SrcDir,File],Contents}], Config0),
+ Pid = proplists:get_value(ftp, Config),
+ ok = ftp:cd(Pid, id2ftp(SrcDir,Config)),
+ ok = ftp:lcd(Pid, id2ftp("",Config)),
+ ok = ftp:recv(Pid, File),
+ chk_file(File, Contents, Config),
+ {error,epath} = ftp:recv(Pid, "non_existing_file"),
+ ok.
+
+%%-------------------------------------------------------------------------
+recv_3() ->
+ [{doc,"Receive a file using recv/3"}].
+recv_3(Config0) ->
+ DstFile = "f_src.txt",
+ SrcFile = "f_dst.txt",
+ Contents = <<"ftp_SUITE test ...">>,
+ Config = set_state([reset, {mkfile,SrcFile,Contents}], Config0),
+ Pid = proplists:get_value(ftp, Config),
+ ok = ftp:cd(Pid, id2ftp("",Config)),
+ ok = ftp:recv(Pid, SrcFile, id2abs(DstFile,Config)),
+ chk_file(DstFile, Contents, Config).
+
+%%-------------------------------------------------------------------------
+recv_bin() ->
+ [{doc, "Receive a file as a binary."}].
+recv_bin(Config0) ->
+ File = "f_dst.txt",
+ Contents = <<"ftp_SUITE test ...">>,
+ Config = set_state([reset, {mkfile,File,Contents}], Config0),
+ Pid = proplists:get_value(ftp, Config),
+ {ok,Received} = ftp:recv_bin(Pid, id2ftp(File,Config)),
+ find_diff(Received, Contents),
+ {error,epath} = ftp:recv_bin(Pid, id2ftp("non_existing_file",Config)),
+ ok.
+
+%%-------------------------------------------------------------------------
+recv_chunk() ->
+ [{doc, "Receive a file using chunk-wise."}].
+recv_chunk(Config0) ->
+ File = "big_file.txt",
+ Contents = list_to_binary( lists:duplicate(1000, lists:seq(0,255)) ),
+ Config = set_state([reset, {mkfile,File,Contents}], Config0),
+ Pid = proplists:get_value(ftp, Config),
+ {{error, "ftp:recv_chunk_start/2 not called"},_} = recv_chunk(Pid, <<>>),
+ ok = ftp:recv_chunk_start(Pid, id2ftp(File,Config)),
+ {ok, ReceivedContents, _Ncunks} = recv_chunk(Pid, <<>>),
+ find_diff(ReceivedContents, Contents).
+
+recv_chunk(Pid, Acc) ->
+ recv_chunk(Pid, Acc, 0).
+
+recv_chunk(Pid, Acc, N) ->
+ case ftp:recv_chunk(Pid) of
+ ok -> {ok, Acc, N};
+ {ok, Bin} -> recv_chunk(Pid, <<Acc/binary, Bin/binary>>, N+1);
+ Error -> {Error, N}
+ end.
+
+%%-------------------------------------------------------------------------
+type() ->
+ [{doc,"Test that we can change btween ASCCI and binary transfer mode"}].
+type(Config) ->
+ Pid = proplists:get_value(ftp, Config),
+ ok = ftp:type(Pid, ascii),
+ ok = ftp:type(Pid, binary),
+ ok = ftp:type(Pid, ascii),
+ {error, etype} = ftp:type(Pid, foobar).
+
+%%-------------------------------------------------------------------------
+quote(Config) ->
+ Pid = proplists:get_value(ftp, Config),
+ ["257 \""++_Rest] = ftp:quote(Pid, "pwd"), %% 257
+ [_| _] = ftp:quote(Pid, "help"),
+ %% This negativ test causes some ftp servers to hang. This test
+ %% is not important for the client, so we skip it for now.
+ %%["425 Can't build data connection: Connection refused."]
+ %% = ftp:quote(Pid, "list"),
+ ok.
+
+%%-------------------------------------------------------------------------
+progress_report_send() ->
+ [{doc, "Test the option progress for ftp:send/[2,3]"}].
+progress_report_send(Config) when is_list(Config) ->
+ ReportPid =
+ spawn_link(?MODULE, progress_report_receiver_init, [self(), 1]),
+ send(Config),
+ receive
+ {ReportPid, ok} ->
+ ok
+ end.
+
+%%-------------------------------------------------------------------------
+progress_report_recv() ->
+ [{doc, "Test the option progress for ftp:recv/[2,3]"}].
+progress_report_recv(Config) when is_list(Config) ->
+ ReportPid =
+ spawn_link(?MODULE, progress_report_receiver_init, [self(), 3]),
+ recv(Config),
+ receive
+ {ReportPid, ok} ->
+ ok
+ end.
+
+%%-------------------------------------------------------------------------
+
+not_owner() ->
+ [{doc, "Test what happens if a process that not owns the connection tries "
+ "to use it"}].
+not_owner(Config) when is_list(Config) ->
+ Pid = proplists:get_value(ftp, Config),
+
+ Parent = self(),
+ OtherPid = spawn_link(
+ fun() ->
+ {error, not_connection_owner} = ftp:pwd(Pid),
+ ftp:close(Pid),
+ Parent ! {self(), ok}
+ end),
+ receive
+ {OtherPid, ok} ->
+ {ok, _} = ftp:pwd(Pid)
+ end.
+
+
+%%-------------------------------------------------------------------------
+
+
+unexpected_call()->
+ [{doc, "Test that behaviour of the ftp process if the api is abused"}].
+unexpected_call(Config) when is_list(Config) ->
+ Flag = process_flag(trap_exit, true),
+ Pid = proplists:get_value(ftp, Config),
+
+ %% Serious programming fault, connetion will be shut down
+ case (catch gen_server:call(Pid, {self(), foobar, 10}, infinity)) of
+ {error, {connection_terminated, 'API_violation'}} ->
+ ok;
+ Unexpected1 ->
+ exit({unexpected_result, Unexpected1})
+ end,
+ ct:sleep(500),
+ undefined = process_info(Pid, status),
+ process_flag(trap_exit, Flag).
+%%-------------------------------------------------------------------------
+
+unexpected_cast()->
+ [{doc, "Test that behaviour of the ftp process if the api is abused"}].
+unexpected_cast(Config) when is_list(Config) ->
+ Flag = process_flag(trap_exit, true),
+ Pid = proplists:get_value(ftp, Config),
+ %% Serious programming fault, connetion will be shut down
+ gen_server:cast(Pid, {self(), foobar, 10}),
+ ct:sleep(500),
+ undefined = process_info(Pid, status),
+ process_flag(trap_exit, Flag).
+%%-------------------------------------------------------------------------
+
+unexpected_bang()->
+ [{doc, "Test that connection ignores unexpected bang"}].
+unexpected_bang(Config) when is_list(Config) ->
+ Flag = process_flag(trap_exit, true),
+ Pid = proplists:get_value(ftp, Config),
+ %% Could be an innocent misstake the connection lives.
+ Pid ! foobar,
+ ct:sleep(500),
+ {status, _} = process_info(Pid, status),
+ process_flag(trap_exit, Flag).
+
+%%-------------------------------------------------------------------------
+
+clean_shutdown() ->
+ [{doc, "Test that owning process that exits with reason "
+ "'shutdown' does not cause an error message. OTP 6035"}].
+
+clean_shutdown(Config) ->
+ Parent = self(),
+ HelperPid = spawn(
+ fun() ->
+ ftp__open(Config, [verbose]),
+ Parent ! ok,
+ receive
+ nothing -> ok
+ end
+ end),
+ receive
+ ok ->
+ PrivDir = proplists:get_value(priv_dir, Config),
+ LogFile = filename:join([PrivDir,"ticket_6035.log"]),
+ error_logger:logfile({open, LogFile}),
+ exit(HelperPid, shutdown),
+ timer:sleep(2000),
+ error_logger:logfile(close),
+ case is_error_report_6035(LogFile) of
+ true -> ok;
+ false -> {fail, "Bad logfile"}
+ end
+ end.
+
+%%%----------------------------------------------------------------
+%%% Error codes not tested elsewhere
+
+error_elogin(Config0) ->
+ Dir = "test",
+ OldFile = "old.txt",
+ NewFile = "new.txt",
+ SrcDir = "data",
+ File = "file.txt",
+ Config = set_state([reset,
+ {mkdir,Dir},
+ {mkfile,OldFile,<<"Contents..">>},
+ {mkfile,[SrcDir,File],<<"Contents..">>}], Config0),
+
+ Pid = proplists:get_value(ftp, Config),
+ ok = ftp:lcd(Pid, id2ftp(SrcDir,Config)),
+ {error,elogin} = ftp:send(Pid, File),
+ ok = ftp:lcd(Pid, id2ftp("",Config)),
+ {error,elogin} = ftp:pwd(Pid),
+ {error,elogin} = ftp:cd(Pid, id2ftp(Dir,Config)),
+ {error,elogin} = ftp:rename(Pid,
+ id2ftp(OldFile,Config),
+ id2ftp(NewFile,Config)),
+ ok.
+
+error_ehost(_Config) ->
+ {error, ehost} = ftp:open("nohost.nodomain"),
+ ok.
+
+%%--------------------------------------------------------------------
+%% Internal functions -----------------------------------------------
+%%--------------------------------------------------------------------
+
+make_cert_files(Alg1, Alg2, Prefix, Dir) ->
+ CaInfo = {CaCert,_} = erl_make_certs:make_cert([{key,Alg1}]),
+ {Cert,CertKey} = erl_make_certs:make_cert([{key,Alg2},{issuer,CaInfo}]),
+ CaCertFile = filename:join(Dir, Prefix++"cacerts.pem"),
+ CertFile = filename:join(Dir, Prefix++"cert.pem"),
+ KeyFile = filename:join(Dir, Prefix++"key.pem"),
+ der_to_pem(CaCertFile, [{'Certificate', CaCert, not_encrypted}]),
+ der_to_pem(CertFile, [{'Certificate', Cert, not_encrypted}]),
+ der_to_pem(KeyFile, [CertKey]),
+ ok.
+
+der_to_pem(File, Entries) ->
+ PemBin = public_key:pem_encode(Entries),
+ file:write_file(File, PemBin).
+
+%%--------------------------------------------------------------------
+chk_file(Path=[C|_], ExpectedContents, Config) when 0<C,C=<255 ->
+ chk_file([Path], ExpectedContents, Config);
+
+chk_file(PathList, ExpectedContents, Config) ->
+ Path = filename:join(PathList),
+ AbsPath = id2abs(Path,Config),
+ case file:read_file(AbsPath) of
+ {ok,ExpectedContents} ->
+ true;
+ {ok,ReadContents} ->
+ {error,{diff,Pos,RC,LC}} = find_diff(ReadContents, ExpectedContents, 1),
+ ct:log("Bad contents of ~p.~nGot:~n~p~nExpected:~n~p~nDiff at pos ~p ~nRead: ~p~nExp : ~p",
+ [AbsPath,ReadContents,ExpectedContents,Pos,RC,LC]),
+ ct:fail("Bad contents of ~p", [Path]);
+ {error,Error} ->
+ try begin
+ {ok,CWD} = file:get_cwd(),
+ ct:log("file:get_cwd()=~p~nfiles:~n~p",[CWD,file:list_dir(CWD)])
+ end
+ of _ -> ok
+ catch _:_ ->ok
+ end,
+ ct:fail("Error reading ~p: ~p",[Path,Error])
+ end.
+
+
+chk_no_file(Path=[C|_], Config) when 0<C,C=<255 ->
+ chk_no_file([Path], Config);
+
+chk_no_file(PathList, Config) ->
+ Path = filename:join(PathList),
+ AbsPath = id2abs(Path,Config),
+ case file:read_file(AbsPath) of
+ {error,enoent} ->
+ true;
+ {ok,Contents} ->
+ ct:log("File ~p exists although it shouldn't. Contents:~n~p",
+ [AbsPath,Contents]),
+ ct:fail("File exists: ~p", [Path]);
+ {error,Error} ->
+ ct:fail("Unexpected error reading ~p: ~p",[Path,Error])
+ end.
+
+
+chk_dir(Path=[C|_], Config) when 0<C,C=<255 ->
+ chk_dir([Path], Config);
+
+chk_dir(PathList, Config) ->
+ Path = filename:join(PathList),
+ AbsPath = id2abs(Path,Config),
+ case file:read_file_info(AbsPath) of
+ {ok, #file_info{type=directory}} ->
+ true;
+ {ok, #file_info{type=Type}} ->
+ ct:fail("Expected dir ~p is a ~p",[Path,Type]);
+ {error,Error} ->
+ ct:fail("Expected dir ~p: ~p",[Path,Error])
+ end.
+
+chk_no_dir(PathList, Config) ->
+ Path = filename:join(PathList),
+ AbsPath = id2abs(Path,Config),
+ case file:read_file_info(AbsPath) of
+ {error,enoent} ->
+ true;
+ {ok, #file_info{type=directory}} ->
+ ct:fail("Dir ~p erroneously exists",[Path]);
+ {ok, #file_info{type=Type}} ->
+ ct:fail("~p ~p erroneously exists",[Type,Path]);
+ {error,Error} ->
+ ct:fail("Unexpected error for ~p: ~p",[Path,Error])
+ end.
+
+%%--------------------------------------------------------------------
+find_executable(Config) ->
+ search_executable(proplists:get_value(ftpservers, Config, ?default_ftp_servers)).
+
+
+search_executable([{Name,Paths,_StartCmd,_ChkUp,_StopCommand,_ConfigUpd,_Host,_Port}|Srvrs]) ->
+ case os_find(Name,Paths) of
+ false ->
+ ct:log("~p not found",[Name]),
+ search_executable(Srvrs);
+ AbsName ->
+ ct:comment("Found ~p",[AbsName]),
+ {ok, {AbsName,_StartCmd,_ChkUp,_StopCommand,_ConfigUpd,_Host,_Port}}
+ end;
+search_executable([]) ->
+ false.
+
+
+os_find(Name, Paths) ->
+ case os:find_executable(Name, Paths) of
+ false -> os:find_executable(Name);
+ AbsName -> AbsName
+ end.
+
+%%%----------------------------------------------------------------
+start_ftpd(Config0) ->
+ {AbsName,StartCmd,_ChkUp,_StopCommand,ConfigRewrite,Host,Port} =
+ proplists:get_value(ftpd_data, Config0),
+ case StartCmd(Config0, AbsName) of
+ {ok,StartResult} ->
+ Config = [{ftpd_host,Host},
+ {ftpd_port,Port},
+ {ftpd_start_result,StartResult} | ConfigRewrite(Config0)],
+ try
+ ftp__close(ftp__open(Config,[verbose]))
+ of
+ Config1 when is_list(Config1) ->
+ ct:log("Usuable ftp server ~p started on ~p:~p",[AbsName,Host,Port]),
+ Config
+ catch
+ Class:Exception ->
+ ct:log("Ftp server ~p started on ~p:~p but is unusable:~n~p:~p",
+ [AbsName,Host,Port,Class,Exception]),
+ {skip, [AbsName," started but unusuable"]}
+ end;
+ {error,Msg} ->
+ {skip, [AbsName," not started: ",Msg]}
+ end.
+
+stop_ftpd(Config) ->
+ {_Name,_StartCmd,_ChkUp,StopCommand,_ConfigUpd,_Host,_Port} = proplists:get_value(ftpd_data, Config),
+ StopCommand(proplists:get_value(ftpd_start_result,Config)).
+
+ps_ftpd(Config) ->
+ {_Name,_StartCmd,ChkUp,_StopCommand,_ConfigUpd,_Host,_Port} = proplists:get_value(ftpd_data, Config),
+ ct:log( ChkUp(proplists:get_value(ftpd_start_result,Config)) ).
+
+
+ftpd_running(Config) ->
+ {_Name,_StartCmd,ChkUp,_StopCommand,_ConfigUpd,_Host,_Port} = proplists:get_value(ftpd_data, Config),
+ ChkUp(proplists:get_value(ftpd_start_result,Config)).
+
+ftp__open(Config, Options) ->
+ Host = proplists:get_value(ftpd_host,Config),
+ Port = proplists:get_value(ftpd_port,Config),
+ ct:log("Host=~p, Port=~p",[Host,Port]),
+ {ok,Pid} = ftp:open(Host, [{port,Port} | Options]),
+ [{ftp,Pid}|Config].
+
+ftp__close(Config) ->
+ ok = ftp:close(proplists:get_value(ftp,Config)),
+ Config.
+
+split(Cs) -> string:tokens(Cs, "\r\n").
+
+find_diff(Bin1, Bin2) ->
+ case find_diff(Bin1, Bin2, 1) of
+ {error, {diff,Pos,RC,LC}} ->
+ ct:log("Contents differ at position ~p.~nOp1: ~p~nOp2: ~p",[Pos,RC,LC]),
+ ct:fail("Contents differ at pos ~p",[Pos]);
+ Other ->
+ Other
+ end.
+
+find_diff(A, A, _) -> true;
+find_diff(<<H,T1/binary>>, <<H,T2/binary>>, Pos) -> find_diff(T1, T2, Pos+1);
+find_diff(RC, LC, Pos) -> {error, {diff, Pos, RC, LC}}.
+
+set_state(Ops, Config) when is_list(Ops) -> lists:foldl(fun set_state/2, Config, Ops);
+
+set_state(reset, Config) ->
+ rm('*', id2abs("",Config)),
+ PrivDir = proplists:get_value(priv_dir,Config),
+ file:set_cwd(PrivDir),
+ ftp:lcd(proplists:get_value(ftp,Config),PrivDir),
+ set_state({mkdir,""},Config);
+set_state({mkdir,Id}, Config) ->
+ Abs = id2abs(Id, Config),
+ mk_path(Abs),
+ file:make_dir(Abs),
+ Config;
+set_state({mkfile,Id,Contents}, Config) ->
+ Abs = id2abs(Id, Config),
+ mk_path(Abs),
+ ok = file:write_file(Abs, Contents),
+ Config.
+
+mk_path(Abs) -> lists:foldl(fun mk_path/2, [], filename:split(filename:dirname(Abs))).
+
+mk_path(F, Pfx) ->
+ case file:read_file_info(AbsName=filename:join(Pfx,F)) of
+ {ok,#file_info{type=directory}} ->
+ AbsName;
+ {error,eexist} ->
+ AbsName;
+ {error,enoent} ->
+ ok = file:make_dir(AbsName),
+ AbsName
+ end.
+
+rm('*', Pfx) ->
+ {ok,Fs} = file:list_dir(Pfx),
+ lists:foreach(fun(F) -> rm(F, Pfx) end, Fs);
+rm(F, Pfx) ->
+ case file:read_file_info(AbsName=filename:join(Pfx,F)) of
+ {ok,#file_info{type=directory}} ->
+ {ok,Fs} = file:list_dir(AbsName),
+ lists:foreach(fun(F1) -> rm(F1,AbsName) end, Fs),
+ ok = file:del_dir(AbsName);
+
+ {ok,#file_info{type=regular}} ->
+ ok = file:delete(AbsName);
+
+ {error,enoent} ->
+ ok
+ end.
+
+id2abs(Id, Conf) -> filename:join(proplists:get_value(priv_dir,Conf),ids(Id)).
+id2ftp(Id, Conf) -> (proplists:get_value(id2ftp,Conf))(ids(Id)).
+id2ftp_result(Id, Conf) -> (proplists:get_value(id2ftp_result,Conf))(ids(Id)).
+
+ids([[_|_]|_]=Ids) -> filename:join(Ids);
+ids(Id) -> Id.
+
+
+is_expected_absName(Id, File, Conf) -> File = (proplists:get_value(id2abs,Conf))(Id).
+is_expected_ftpInName(Id, File, Conf) -> File = (proplists:get_value(id2ftp,Conf))(Id).
+is_expected_ftpOutName(Id, File, Conf) -> File = (proplists:get_value(id2ftp_result,Conf))(Id).
+
+
+%%%----------------------------------------------------------------
+%%% Help functions for the option '{progress,Progress}'
+%%%
+
+%%%----------------
+%%% Callback:
+
+progress(#progress{} = P, _File, {file_size, Total} = M) ->
+ ct:pal("Progress: ~p",[M]),
+ progress_report_receiver ! start,
+ P#progress{total = Total};
+
+progress(#progress{current = Current} = P, _File, {transfer_size, 0} = M) ->
+ ct:pal("Progress: ~p",[M]),
+ progress_report_receiver ! finish,
+ case P#progress.total of
+ unknown -> P;
+ Current -> P;
+ Total -> ct:fail({error, {progress, {total,Total}, {current,Current}}}),
+ P
+ end;
+
+progress(#progress{current = Current} = P, _File, {transfer_size, Size} = M) ->
+ ct:pal("Progress: ~p",[M]),
+ progress_report_receiver ! update,
+ P#progress{current = Current + Size};
+
+progress(P, _File, M) ->
+ ct:pal("Progress **** Strange: ~p",[M]),
+ P.
+
+
+%%%----------------
+%%% Help process that counts the files transferred:
+
+progress_report_receiver_init(Parent, N) ->
+ register(progress_report_receiver, self()),
+ progress_report_receiver_expect_N_files(Parent, N).
+
+progress_report_receiver_expect_N_files(_Parent, 0) ->
+ ct:pal("progress_report got all files!", []);
+progress_report_receiver_expect_N_files(Parent, N) ->
+ ct:pal("progress_report expects ~p more files",[N]),
+ receive
+ start -> ok
+ end,
+ progress_report_receiver_loop(Parent, N-1).
+
+
+progress_report_receiver_loop(Parent, N) ->
+ ct:pal("progress_report expect update | finish. N = ~p",[N]),
+ receive
+ update ->
+ ct:pal("progress_report got update",[]),
+ progress_report_receiver_loop(Parent, N);
+ finish ->
+ ct:pal("progress_report got finish, send ~p to ~p",[{self(),ok}, Parent]),
+ Parent ! {self(), ok},
+ progress_report_receiver_expect_N_files(Parent, N)
+ end.
+
+%%%----------------------------------------------------------------
+%%% Help functions for bug OTP-6035
+
+is_error_report_6035(LogFile) ->
+ case file:read_file(LogFile) of
+ {ok, Bin} ->
+ nomatch =/= binary:match(Bin, <<"=ERROR REPORT====">>);
+ _ ->
+ false
+ end.
+
diff --git a/lib/inets/test/ftp_SUITE_data/vsftpd.conf b/lib/inets/test/ftp_SUITE_data/vsftpd.conf
new file mode 100644
index 0000000000..a5584f5916
--- /dev/null
+++ b/lib/inets/test/ftp_SUITE_data/vsftpd.conf
@@ -0,0 +1,26 @@
+
+###
+### Some parameters are given in the vsftpd start command.
+###
+### Typical command-line paramters are such that has a file path
+### component like cert files.
+###
+
+
+listen=YES
+listen_port=9999
+run_as_launching_user=YES
+ssl_enable=YES
+allow_anon_ssl=YES
+
+background=YES
+
+write_enable=YES
+anonymous_enable=YES
+anon_upload_enable=YES
+anon_mkdir_write_enable=YES
+anon_other_write_enable=YES
+anon_world_readable_only=NO
+
+### Shouldn't be necessary....
+require_ssl_reuse=NO
diff --git a/lib/inets/test/ftp_format_SUITE.erl b/lib/inets/test/ftp_format_SUITE.erl
index 16e5cdb4bc..a33b31f46f 100644
--- a/lib/inets/test/ftp_format_SUITE.erl
+++ b/lib/inets/test/ftp_format_SUITE.erl
@@ -1,18 +1,19 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2005-2013. All Rights Reserved.
+%% Copyright Ericsson AB 2005-2016. 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.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
+%%
+%% http://www.apache.org/licenses/LICENSE-2.0
+%%
+%% Unless required by applicable law or agreed to in writing, software
+%% distributed under the License is distributed on an "AS IS" BASIS,
+%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+%% See the License for the specific language governing permissions and
+%% limitations under the License.
%%
%% %CopyrightEnd%
%%
@@ -21,21 +22,15 @@
-author('[email protected]').
-include_lib("common_test/include/ct.hrl").
--include("test_server_line.hrl").
-include("ftp_internal.hrl").
-%% Test server specific exports
--export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1,
- init_per_group/2,end_per_group/2,
- init_per_testcase/2, end_per_testcase/2]).
-
-%% Test cases must be exported.
--export([ ftp_150/1,
- ftp_200/1, ftp_220/1, ftp_226/1, ftp_257/1, ftp_331/1, ftp_425/1,
- ftp_other_status_codes/1, ftp_multiple_lines/1,
- ftp_multipel_ctrl_messages/1, format_error/1]).
+%% Note: This directive should only be used in test suites.
+-compile(export_all).
-suite() -> [{ct_hooks,[ts_install_cth]}].
+suite() ->
+ [{ct_hooks,[ts_install_cth]},
+ {timetrap,{seconds,5}}
+ ].
all() ->
[{group, ftp_response}, format_error].
@@ -60,23 +55,16 @@ end_per_group(_GroupName, Config) ->
init_per_testcase(_, Config) ->
- Dog = test_server:timetrap(?t:minutes(1)),
- NewConfig = lists:keydelete(watchdog, 1, Config),
- [{watchdog, Dog} | NewConfig].
-
-end_per_testcase(_, Config) ->
- Dog = ?config(watchdog, Config),
- test_server:timetrap_cancel(Dog),
+ Config.
+end_per_testcase(_, _) ->
ok.
%%-------------------------------------------------------------------------
%% Test cases starts here.
%%-------------------------------------------------------------------------
-ftp_150(doc) ->
- ["Especially check that respons can be devided in a random place."];
-ftp_150(suite) ->
- [];
+ftp_150() ->
+ [{doc, "Especially check that respons can be devided in a random place."}].
ftp_150(Config) when is_list(Config) ->
FtpResponse = ["150 ASCII data conn", "ection for /bin/ls ",
"(134.138.177", ".89,50434) (0 bytes).\r\n"],
@@ -84,14 +72,11 @@ ftp_150(Config) when is_list(Config) ->
"150 ASCII data connection for /bin/ls "
"(134.138.177.89,50434) (0 bytes).\r\n" = Msg =
parse(ftp_response, parse_lines, [[], start], FtpResponse),
- {pos_prel, _} = ftp_response:interpret(Msg),
- ok.
-
-ftp_200(doc) ->
- ["Especially check that respons can be devided after the first status "
- "code character and in the end delimiter."];
-ftp_200(suite) ->
- [];
+ {pos_prel, _} = ftp_response:interpret(Msg).
+
+ftp_200() ->
+ [{doc, "Especially check that respons can be devided after the first status "
+ "code character and in the end delimiter."}].
ftp_200(Config) when is_list(Config) ->
FtpResponse = ["2", "00 PORT command successful.", [?CR], [?LF]],
@@ -100,11 +85,9 @@ ftp_200(Config) when is_list(Config) ->
{pos_compl, _} = ftp_response:interpret(Msg),
ok.
-ftp_220(doc) ->
- ["Especially check that respons can be devided after the "
- "first with space "];
-ftp_220(suite) ->
- [];
+ftp_220() ->
+ [{doc, "Especially check that respons can be devided after the "
+ "first with space "}].
ftp_220(Config) when is_list(Config) ->
FtpResponse = ["220 ","fingon FTP server (SunOS 5.8) ready.\r\n"],
@@ -113,11 +96,9 @@ ftp_220(Config) when is_list(Config) ->
{pos_compl, _} = ftp_response:interpret(Msg),
ok.
-ftp_226(doc) ->
- ["Especially check that respons can be devided after second status code"
- " character and in the end delimiter."];
-ftp_226(suite) ->
- [];
+ftp_226() ->
+ [{doc, "Especially check that respons can be devided after second status code"
+ " character and in the end delimiter."}].
ftp_226(Config) when is_list(Config) ->
FtpResponse = ["22" "6 Transfer complete.\r", [?LF]],
@@ -126,10 +107,8 @@ ftp_226(Config) when is_list(Config) ->
{pos_compl, _} = ftp_response:interpret(Msg),
ok.
-ftp_257(doc) ->
- ["Especially check that quoted chars do not cause a problem."];
-ftp_257(suite) ->
- [];
+ftp_257() ->
+ [{doc, "Especially check that quoted chars do not cause a problem."}].
ftp_257(Config) when is_list(Config) ->
FtpResponse = ["257 \"/\" is current directory.\r\n"],
@@ -138,11 +117,9 @@ ftp_257(Config) when is_list(Config) ->
{pos_compl, _} = ftp_response:interpret(Msg),
ok.
-ftp_331(doc) ->
- ["Especially check that respons can be devided after the third status "
- " status code character."];
-ftp_331(suite) ->
- [];
+ftp_331() ->
+ [{doc, "Especially check that respons can be devided after the third status "
+ " status code character."}].
ftp_331(Config) when is_list(Config) ->
%% Brake before white space after code
FtpResponse =
@@ -153,10 +130,8 @@ ftp_331(Config) when is_list(Config) ->
{pos_interm, _} = ftp_response:interpret(Msg),
ok.
-ftp_425(doc) ->
- ["Especially check a message that was received in only one part."];
-ftp_425(suite) ->
- [];
+ftp_425() ->
+ [{doc, "Especially check a message that was received in only one part."}].
ftp_425(Config) when is_list(Config) ->
FtpResponse =
["425 Can't build data connection: Connection refused.\r\n"],
@@ -166,10 +141,8 @@ ftp_425(Config) when is_list(Config) ->
{trans_neg_compl, _} = ftp_response:interpret(Msg),
ok.
-ftp_multiple_lines(doc) ->
- ["Especially check multiple lines devided in significant places"];
-ftp_multiple_lines(suite) ->
- [];
+ftp_multiple_lines() ->
+ [{doc, "Especially check multiple lines devided in significant places"}].
ftp_multiple_lines(Config) when is_list(Config) ->
FtpResponse = ["21", "4","-The",
" following commands are recognized:\r\n"
@@ -247,13 +220,11 @@ ftp_multiple_lines(Config) when is_list(Config) ->
FtpResponse2),
ok.
-ftp_other_status_codes(doc) ->
- ["Check that other valid status codes, than the ones above, are handled"
+ftp_other_status_codes() ->
+ [{doc, "Check that other valid status codes, than the ones above, are handled"
"by ftp_response:interpret/1. Note there are som ftp status codes"
"that will not be received with the current ftp instruction support,"
- "they are not included here."];
-ftp_other_status_codes(suite) ->
- [];
+ "they are not included here."}].
ftp_other_status_codes(Config) when is_list(Config) ->
%% 1XX
@@ -282,18 +253,16 @@ ftp_other_status_codes(Config) when is_list(Config) ->
{perm_neg_compl, _ } = ftp_response:interpret("501 Foobar\r\n"),
{perm_neg_compl, _ } = ftp_response:interpret("503 Foobar\r\n"),
{perm_neg_compl, _ } = ftp_response:interpret("504 Foobar\r\n"),
- {perm_neg_compl, _ } = ftp_response:interpret("530 Foobar\r\n"),
+ {elogin, _ } = ftp_response:interpret("530 Foobar\r\n"),
{perm_neg_compl, _ } = ftp_response:interpret("532 Foobar\r\n"),
{epath, _ } = ftp_response:interpret("550 Foobar\r\n"),
{epnospc, _ } = ftp_response:interpret("552 Foobar\r\n"),
{efnamena, _ } = ftp_response:interpret("553 Foobar\r\n"),
ok.
-ftp_multipel_ctrl_messages(doc) ->
- ["The ftp server may send more than one control message as a reply,"
- "check that they are handled one at the time."];
-ftp_multipel_ctrl_messages(suite) ->
- [];
+ftp_multipel_ctrl_messages() ->
+ [{doc, "The ftp server may send more than one control message as a reply,"
+ "check that they are handled one at the time."}].
ftp_multipel_ctrl_messages(Config) when is_list(Config) ->
FtpResponse = ["200 PORT command successful.\r\n200 Foobar\r\n"],
@@ -306,10 +275,6 @@ ftp_multipel_ctrl_messages(Config) when is_list(Config) ->
%%-------------------------------------------------------------------------
-format_error(doc) ->
- [""];
-format_error(suite) ->
- [];
format_error(Config) when is_list(Config) ->
"Synchronisation error during chunk sending." =
ftp:formaterror(echunk),
@@ -346,7 +311,7 @@ parse(Module, Function, [AccLines, StatusCode], [Data | Rest]) ->
{continue, {NewData, NewAccLines, NewStatusCode}} ->
case Rest of
[] ->
- test_server:fail({wrong_input, Data, Rest});
+ ct:fail({wrong_input, Data, Rest});
[_ | _] ->
parse(Module, Function, [NewAccLines, NewStatusCode],
[binary_to_list(NewData) ++ hd(Rest) | tl(Rest)])
diff --git a/lib/inets/test/ftp_freebsd_x86_test.erl b/lib/inets/test/ftp_freebsd_x86_test.erl
deleted file mode 100644
index 1d66779882..0000000000
--- a/lib/inets/test/ftp_freebsd_x86_test.erl
+++ /dev/null
@@ -1,160 +0,0 @@
-%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2005-2010. 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(ftp_freebsd_x86_test).
-
--compile(export_all).
-
--include_lib("common_test/include/ct.hrl").
-
--define(LIB_MOD,ftp_suite_lib).
--define(CASE_WRAPPER(_A_,_B_,_C_),?LIB_MOD:wrapper(_A_,_B_,_C_)).
--define(PLATFORM,"Freebsd x86 ").
-
-%% Test server callback functions
-%%--------------------------------------------------------------------
-%% 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) ->
- {File, NewFile} = ?LIB_MOD:test_filenames(),
- NewConfig = [{file, File}, {new_file, NewFile} | Config],
- ?LIB_MOD:ftpd_init(freebsd_x86, NewConfig).
-
-%%--------------------------------------------------------------------
-%% 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) ->
- ?LIB_MOD:ftpd_fin(Config).
-
-%%--------------------------------------------------------------------
-%% Function: init_per_testcase(TestCase, 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.
-%% Description: Initiation before each test case
-%%--------------------------------------------------------------------
-init_per_testcase(Case, Config) ->
- ftp_suite_lib:init_per_testcase(Case, Config).
-%%--------------------------------------------------------------------
-%% Function: end_per_testcase(TestCase, 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) ->
- ftp_suite_lib:end_per_testcase(Case, Config).
-
-%%--------------------------------------------------------------------
-%% Function: all(Clause) -> TestCases
-%% Clause - atom() - suite | doc
-%% TestCases - [Case]
-%% Case - atom()
-%% Name of a test case.
-%% Description: Returns a list of all test cases in this test suite
-%%--------------------------------------------------------------------
-all() ->
- [open, open_port, {group, passive}, {group, active},
- api_missuse, not_owner, {group, progress_report}].
-
-groups() ->
- [{passive, [], ftp_suite_lib:passive(suite)},
- {active, [], ftp_suite_lib:active(suite)},
- {progress_report, [],
- ftp_suite_lib:progress_report(suite)}].
-
-init_per_group(_GroupName, Config) ->
- Config.
-
-end_per_group(_GroupName, Config) ->
- Config.
-
-
-%% Test cases starts here.
-%%--------------------------------------------------------------------
-
-open(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:open/1).
-open_port(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:open_port/1).
-api_missuse(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:api_missuse/1).
-not_owner(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:not_owner/1).
-
-passive_user(X) -> ?LIB_MOD:passive_user(X).
-passive_pwd(X) -> ?LIB_MOD:passive_pwd(X).
-passive_cd(X) -> ?LIB_MOD:passive_cd(X).
-passive_lcd(X) -> ?LIB_MOD:passive_lcd(X).
-passive_ls(X) -> ?LIB_MOD:passive_ls(X).
-passive_nlist(X) -> ?LIB_MOD:passive_nlist(X).
-passive_rename(X) -> ?LIB_MOD:passive_rename(X).
-passive_delete(X) -> ?LIB_MOD:passive_delete(X).
-passive_mkdir(X) -> ?LIB_MOD:passive_mkdir(X).
-passive_send(X) -> ?LIB_MOD:passive_send(X).
-passive_send_bin(X) -> ?LIB_MOD:passive_send_bin(X).
-passive_send_chunk(X) -> ?LIB_MOD:passive_send_chunk(X).
-passive_append(X) -> ?LIB_MOD:passive_append(X).
-passive_append_bin(X) -> ?LIB_MOD:passive_append_bin(X).
-passive_append_chunk(X) -> ?LIB_MOD:passive_append_chunk(X).
-passive_recv(X) -> ?LIB_MOD:passive_recv(X).
-passive_recv_bin(X) -> ?LIB_MOD:passive_recv_bin(X).
-passive_recv_chunk(X) -> ?LIB_MOD:passive_recv_chunk(X).
-passive_type(X) -> ?LIB_MOD:passive_type(X).
-passive_quote(X) -> ?LIB_MOD:passive_quote(X).
-passive_ip_v6_disabled(X) -> ?LIB_MOD:passive_ip_v6_disabled(X).
-active_user(X) -> ?LIB_MOD:active_user(X).
-active_pwd(X) -> ?LIB_MOD:active_pwd(X).
-active_cd(X) -> ?LIB_MOD:active_cd(X).
-active_lcd(X) -> ?LIB_MOD:active_lcd(X).
-active_ls(X) -> ?LIB_MOD:active_ls(X).
-active_nlist(X) -> ?LIB_MOD:active_nlist(X).
-active_rename(X) -> ?LIB_MOD:active_rename(X).
-active_delete(X) -> ?LIB_MOD:active_delete(X).
-active_mkdir(X) -> ?LIB_MOD:active_mkdir(X).
-active_send(X) -> ?LIB_MOD:active_send(X).
-active_send_bin(X) -> ?LIB_MOD:active_send_bin(X).
-active_send_chunk(X) -> ?LIB_MOD:active_send_chunk(X).
-active_append(X) -> ?LIB_MOD:active_append(X).
-active_append_bin(X) -> ?LIB_MOD:active_append_bin(X).
-active_append_chunk(X) -> ?LIB_MOD:active_append_chunk(X).
-active_recv(X) -> ?LIB_MOD:active_recv(X).
-active_recv_bin(X) -> ?LIB_MOD:active_recv_bin(X).
-active_recv_chunk(X) -> ?LIB_MOD:active_recv_chunk(X).
-active_type(X) -> ?LIB_MOD:active_type(X).
-active_quote(X) -> ?LIB_MOD:active_quote(X).
-active_ip_v6_disabled(X) -> ?LIB_MOD:active_ip_v6_disabled(X).
-progress_report_send(X) -> ?LIB_MOD:progress_report_send(X).
-progress_report_recv(X) -> ?LIB_MOD:progress_report_recv(X).
-
-fin(Config) ->
- ?LIB_MOD:ftpd_fin(Config).
diff --git a/lib/inets/test/ftp_linux_ppc_test.erl b/lib/inets/test/ftp_linux_ppc_test.erl
deleted file mode 100644
index bba97237f1..0000000000
--- a/lib/inets/test/ftp_linux_ppc_test.erl
+++ /dev/null
@@ -1,158 +0,0 @@
-%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2005-2010. 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(ftp_linux_ppc_test).
-
-%% Note: This directive should only be used in test suites.
--compile(export_all).
-
--include_lib("common_test/include/ct.hrl").
-
--define(LIB_MOD,ftp_suite_lib).
--define(CASE_WRAPPER(_A_,_B_,_C_),?LIB_MOD:wrapper(_A_,_B_,_C_)).
--define(PLATFORM,"Linux ppc ").
-
-%% Test server callback functions
-%%--------------------------------------------------------------------
-%% 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) ->
- {File, NewFile} = ?LIB_MOD:test_filenames(),
- NewConfig = [{file, File}, {new_file, NewFile} | Config],
- ?LIB_MOD:ftpd_init(linux_ppc, NewConfig).
-
-%%--------------------------------------------------------------------
-%% 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) ->
- ?LIB_MOD:ftpd_fin(Config).
-
-%%--------------------------------------------------------------------
-%% Function: init_per_testcase(TestCase, 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.
-%% Description: Initiation before each test case
-%%--------------------------------------------------------------------
-init_per_testcase(Case, Config) ->
- ftp_suite_lib:init_per_testcase(Case, Config).
-%%--------------------------------------------------------------------
-%% Function: end_per_testcase(TestCase, 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) ->
- ftp_suite_lib:end_per_testcase(Case, Config).
-
-%%--------------------------------------------------------------------
-%% Function: all(Clause) -> TestCases
-%% Clause - atom() - suite | doc
-%% TestCases - [Case]
-%% Case - atom()
-%% Name of a test case.
-%% Description: Returns a list of all test cases in this test suite
-%%--------------------------------------------------------------------
-all() ->
- [open, open_port, {group, passive}, {group, active},
- api_missuse, not_owner, {group, progress_report}].
-
-groups() ->
- [{passive, [], ftp_suite_lib:passive(suite)},
- {active, [], ftp_suite_lib:active(suite)},
- {progress_report, [],
- ftp_suite_lib:progress_report(suite)}].
-
-init_per_group(_GroupName, Config) ->
- Config.
-
-end_per_group(_GroupName, Config) ->
- Config.
-
-
-%% Test cases starts here.
-%%--------------------------------------------------------------------
-
-open(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:open/1).
-open_port(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:open_port/1).
-api_missuse(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:api_missuse/1).
-not_owner(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:not_owner/1).
-
-passive_user(X) -> ?LIB_MOD:passive_user(X).
-passive_pwd(X) -> ?LIB_MOD:passive_pwd(X).
-passive_cd(X) -> ?LIB_MOD:passive_cd(X).
-passive_lcd(X) -> ?LIB_MOD:passive_lcd(X).
-passive_ls(X) -> ?LIB_MOD:passive_ls(X).
-passive_nlist(X) -> ?LIB_MOD:passive_nlist(X).
-passive_rename(X) -> ?LIB_MOD:passive_rename(X).
-passive_delete(X) -> ?LIB_MOD:passive_delete(X).
-passive_mkdir(X) -> ?LIB_MOD:passive_mkdir(X).
-passive_send(X) -> ?LIB_MOD:passive_send(X).
-passive_send_bin(X) -> ?LIB_MOD:passive_send_bin(X).
-passive_send_chunk(X) -> ?LIB_MOD:passive_send_chunk(X).
-passive_append(X) -> ?LIB_MOD:passive_append(X).
-passive_append_bin(X) -> ?LIB_MOD:passive_append_bin(X).
-passive_append_chunk(X) -> ?LIB_MOD:passive_append_chunk(X).
-passive_recv(X) -> ?LIB_MOD:passive_recv(X).
-passive_recv_bin(X) -> ?LIB_MOD:passive_recv_bin(X).
-passive_recv_chunk(X) -> ?LIB_MOD:passive_recv_chunk(X).
-passive_type(X) -> ?LIB_MOD:passive_type(X).
-passive_quote(X) -> ?LIB_MOD:passive_quote(X).
-passive_ip_v6_disabled(X) -> ?LIB_MOD:passive_ip_v6_disabled(X).
-active_user(X) -> ?LIB_MOD:active_user(X).
-active_pwd(X) -> ?LIB_MOD:active_pwd(X).
-active_cd(X) -> ?LIB_MOD:active_cd(X).
-active_lcd(X) -> ?LIB_MOD:active_lcd(X).
-active_ls(X) -> ?LIB_MOD:active_ls(X).
-active_nlist(X) -> ?LIB_MOD:active_nlist(X).
-active_rename(X) -> ?LIB_MOD:active_rename(X).
-active_delete(X) -> ?LIB_MOD:active_delete(X).
-active_mkdir(X) -> ?LIB_MOD:active_mkdir(X).
-active_send(X) -> ?LIB_MOD:active_send(X).
-active_send_bin(X) -> ?LIB_MOD:active_send_bin(X).
-active_send_chunk(X) -> ?LIB_MOD:active_send_chunk(X).
-active_append(X) -> ?LIB_MOD:active_append(X).
-active_append_bin(X) -> ?LIB_MOD:active_append_bin(X).
-active_append_chunk(X) -> ?LIB_MOD:active_append_chunk(X).
-active_recv(X) -> ?LIB_MOD:active_recv(X).
-active_recv_bin(X) -> ?LIB_MOD:active_recv_bin(X).
-active_recv_chunk(X) -> ?LIB_MOD:active_recv_chunk(X).
-active_type(X) -> ?LIB_MOD:active_type(X).
-active_quote(X) -> ?LIB_MOD:active_quote(X).
-active_ip_v6_disabled(X) -> ?LIB_MOD:active_ip_v6_disabled(X).
-progress_report_send(X) -> ?LIB_MOD:progress_report_send(X).
-progress_report_recv(X) -> ?LIB_MOD:progress_report_recv(X).
diff --git a/lib/inets/test/ftp_linux_x86_test.erl b/lib/inets/test/ftp_linux_x86_test.erl
deleted file mode 100644
index bbefd8231e..0000000000
--- a/lib/inets/test/ftp_linux_x86_test.erl
+++ /dev/null
@@ -1,160 +0,0 @@
-%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2005-2010. 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(ftp_linux_x86_test).
-
--compile(export_all).
-
--include_lib("common_test/include/ct.hrl").
-
--define(LIB_MOD,ftp_suite_lib).
--define(CASE_WRAPPER(_A_,_B_,_C_),?LIB_MOD:wrapper(_A_,_B_,_C_)).
--define(PLATFORM,"Linux x86 ").
-
-%% Test server callback functions
-%%--------------------------------------------------------------------
-%% 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) ->
- {File, NewFile} = ?LIB_MOD:test_filenames(),
- NewConfig = [{file, File}, {new_file, NewFile} | Config],
- ?LIB_MOD:ftpd_init(linux_x86, NewConfig).
-
-%%--------------------------------------------------------------------
-%% 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) ->
- ?LIB_MOD:ftpd_fin(Config).
-
-%%--------------------------------------------------------------------
-%% Function: init_per_testcase(TestCase, 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.
-%% Description: Initiation before each test case
-%%--------------------------------------------------------------------
-init_per_testcase(Case, Config) ->
- ftp_suite_lib:init_per_testcase(Case, Config).
-%%--------------------------------------------------------------------
-%% Function: end_per_testcase(TestCase, 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) ->
- ftp_suite_lib:end_per_testcase(Case, Config).
-
-%%--------------------------------------------------------------------
-%% Function: all(Clause) -> TestCases
-%% Clause - atom() - suite | doc
-%% TestCases - [Case]
-%% Case - atom()
-%% Name of a test case.
-%% Description: Returns a list of all test cases in this test suite
-%%--------------------------------------------------------------------
-all() ->
- [open, open_port, {group, passive}, {group, active},
- api_missuse, not_owner, {group, progress_report}].
-
-groups() ->
- [{passive, [], ftp_suite_lib:passive(suite)},
- {active, [], ftp_suite_lib:active(suite)},
- {progress_report, [],
- ftp_suite_lib:progress_report(suite)}].
-
-init_per_group(_GroupName, Config) ->
- Config.
-
-end_per_group(_GroupName, Config) ->
- Config.
-
-
-%% Test cases starts here.
-%%--------------------------------------------------------------------
-
-open(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:open/1).
-open_port(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:open_port/1).
-api_missuse(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:api_missuse/1).
-not_owner(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:not_owner/1).
-
-passive_user(X) -> ?LIB_MOD:passive_user(X).
-passive_pwd(X) -> ?LIB_MOD:passive_pwd(X).
-passive_cd(X) -> ?LIB_MOD:passive_cd(X).
-passive_lcd(X) -> ?LIB_MOD:passive_lcd(X).
-passive_ls(X) -> ?LIB_MOD:passive_ls(X).
-passive_nlist(X) -> ?LIB_MOD:passive_nlist(X).
-passive_rename(X) -> ?LIB_MOD:passive_rename(X).
-passive_delete(X) -> ?LIB_MOD:passive_delete(X).
-passive_mkdir(X) -> ?LIB_MOD:passive_mkdir(X).
-passive_send(X) -> ?LIB_MOD:passive_send(X).
-passive_send_bin(X) -> ?LIB_MOD:passive_send_bin(X).
-passive_send_chunk(X) -> ?LIB_MOD:passive_send_chunk(X).
-passive_append(X) -> ?LIB_MOD:passive_append(X).
-passive_append_bin(X) -> ?LIB_MOD:passive_append_bin(X).
-passive_append_chunk(X) -> ?LIB_MOD:passive_append_chunk(X).
-passive_recv(X) -> ?LIB_MOD:passive_recv(X).
-passive_recv_bin(X) -> ?LIB_MOD:passive_recv_bin(X).
-passive_recv_chunk(X) -> ?LIB_MOD:passive_recv_chunk(X).
-passive_type(X) -> ?LIB_MOD:passive_type(X).
-passive_quote(X) -> ?LIB_MOD:passive_quote(X).
-passive_ip_v6_disabled(X) -> ?LIB_MOD:passive_ip_v6_disabled(X).
-active_user(X) -> ?LIB_MOD:active_user(X).
-active_pwd(X) -> ?LIB_MOD:active_pwd(X).
-active_cd(X) -> ?LIB_MOD:active_cd(X).
-active_lcd(X) -> ?LIB_MOD:active_lcd(X).
-active_ls(X) -> ?LIB_MOD:active_ls(X).
-active_nlist(X) -> ?LIB_MOD:active_nlist(X).
-active_rename(X) -> ?LIB_MOD:active_rename(X).
-active_delete(X) -> ?LIB_MOD:active_delete(X).
-active_mkdir(X) -> ?LIB_MOD:active_mkdir(X).
-active_send(X) -> ?LIB_MOD:active_send(X).
-active_send_bin(X) -> ?LIB_MOD:active_send_bin(X).
-active_send_chunk(X) -> ?LIB_MOD:active_send_chunk(X).
-active_append(X) -> ?LIB_MOD:active_append(X).
-active_append_bin(X) -> ?LIB_MOD:active_append_bin(X).
-active_append_chunk(X) -> ?LIB_MOD:active_append_chunk(X).
-active_recv(X) -> ?LIB_MOD:active_recv(X).
-active_recv_bin(X) -> ?LIB_MOD:active_recv_bin(X).
-active_recv_chunk(X) -> ?LIB_MOD:active_recv_chunk(X).
-active_type(X) -> ?LIB_MOD:active_type(X).
-active_quote(X) -> ?LIB_MOD:active_quote(X).
-active_ip_v6_disabled(X) -> ?LIB_MOD:active_ip_v6_disabled(X).
-progress_report_send(X) -> ?LIB_MOD:progress_report_send(X).
-progress_report_recv(X) -> ?LIB_MOD:progress_report_recv(X).
-
-fin(Config) ->
- ?LIB_MOD:ftpd_fin(Config).
diff --git a/lib/inets/test/ftp_macosx_ppc_test.erl b/lib/inets/test/ftp_macosx_ppc_test.erl
deleted file mode 100644
index c9f33b8beb..0000000000
--- a/lib/inets/test/ftp_macosx_ppc_test.erl
+++ /dev/null
@@ -1,159 +0,0 @@
-%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2005-2010. 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(ftp_macosx_ppc_test).
-
--compile(export_all).
-
--include_lib("common_test/include/ct.hrl").
-
--define(LIB_MOD,ftp_suite_lib).
--define(CASE_WRAPPER(_A_,_B_,_C_),?LIB_MOD:wrapper(_A_,_B_,_C_)).
--define(PLATFORM,"Macosx ppc ").
-
-
-%% Test server callback functions
-%%--------------------------------------------------------------------
-%% 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) ->
- {File, NewFile} = ?LIB_MOD:test_filenames(),
- NewConfig = [{file, File}, {new_file, NewFile} | Config],
- ?LIB_MOD:ftpd_init(macosx_ppc, NewConfig).
-
-%%--------------------------------------------------------------------
-%% 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) ->
- ?LIB_MOD:ftpd_fin(Config).
-
-%%--------------------------------------------------------------------
-%% Function: init_per_testcase(TestCase, 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.
-%% Description: Initiation before each test case
-%%--------------------------------------------------------------------
-init_per_testcase(Case, Config) ->
- ftp_suite_lib:init_per_testcase(Case, Config).
-%%--------------------------------------------------------------------
-%% Function: end_per_testcase(TestCase, 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) ->
- ftp_suite_lib:end_per_testcase(Case, Config).
-
-%%--------------------------------------------------------------------
-%% Function: all(Clause) -> TestCases
-%% Clause - atom() - suite | doc
-%% TestCases - [Case]
-%% Case - atom()
-%% Name of a test case.
-%% Description: Returns a list of all test cases in this test suite
-%%--------------------------------------------------------------------
-all() ->
-[open, open_port, {group, passive}, {group, active},
- api_missuse, not_owner, {group, progress_report}].
-
-groups() ->
- [{passive, [], ftp_suite_lib:passive(suite)},
- {active, [], ftp_suite_lib:active(suite)},
- {progress_report, [],
- ftp_suite_lib:progress_report(suite)}].
-
-init_per_group(_GroupName, Config) ->
- Config.
-
-end_per_group(_GroupName, Config) ->
- Config.
-
-
-
-open(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:open/1).
-open_port(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:open_port/1).
-api_missuse(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:api_missuse/1).
-not_owner(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:not_owner/1).
-
-passive_user(X) -> ?LIB_MOD:passive_user(X).
-passive_pwd(X) -> ?LIB_MOD:passive_pwd(X).
-passive_cd(X) -> ?LIB_MOD:passive_cd(X).
-passive_lcd(X) -> ?LIB_MOD:passive_lcd(X).
-passive_ls(X) -> ?LIB_MOD:passive_ls(X).
-passive_nlist(X) -> ?LIB_MOD:passive_nlist(X).
-passive_rename(X) -> ?LIB_MOD:passive_rename(X).
-passive_delete(X) -> ?LIB_MOD:passive_delete(X).
-passive_mkdir(X) -> ?LIB_MOD:passive_mkdir(X).
-passive_send(X) -> ?LIB_MOD:passive_send(X).
-passive_send_bin(X) -> ?LIB_MOD:passive_send_bin(X).
-passive_send_chunk(X) -> ?LIB_MOD:passive_send_chunk(X).
-passive_append(X) -> ?LIB_MOD:passive_append(X).
-passive_append_bin(X) -> ?LIB_MOD:passive_append_bin(X).
-passive_append_chunk(X) -> ?LIB_MOD:passive_append_chunk(X).
-passive_recv(X) -> ?LIB_MOD:passive_recv(X).
-passive_recv_bin(X) -> ?LIB_MOD:passive_recv_bin(X).
-passive_recv_chunk(X) -> ?LIB_MOD:passive_recv_chunk(X).
-passive_type(X) -> ?LIB_MOD:passive_type(X).
-passive_quote(X) -> ?LIB_MOD:passive_quote(X).
-passive_ip_v6_disabled(_X) -> {skipped,"unknown error"}.%?LIB_MOD:passive_ip_v6_disabled(X).
-active_user(X) -> ?LIB_MOD:active_user(X).
-active_pwd(X) -> ?LIB_MOD:active_pwd(X).
-active_cd(X) -> ?LIB_MOD:active_cd(X).
-active_lcd(X) -> ?LIB_MOD:active_lcd(X).
-active_ls(X) -> ?LIB_MOD:active_ls(X).
-active_nlist(X) -> ?LIB_MOD:active_nlist(X).
-active_rename(X) -> ?LIB_MOD:active_rename(X).
-active_delete(X) -> ?LIB_MOD:active_delete(X).
-active_mkdir(X) -> ?LIB_MOD:active_mkdir(X).
-active_send(X) -> ?LIB_MOD:active_send(X).
-active_send_bin(X) -> ?LIB_MOD:active_send_bin(X).
-active_send_chunk(X) -> ?LIB_MOD:active_send_chunk(X).
-active_append(X) -> ?LIB_MOD:active_append(X).
-active_append_bin(X) -> ?LIB_MOD:active_append_bin(X).
-active_append_chunk(X) -> ?LIB_MOD:active_append_chunk(X).
-active_recv(X) -> ?LIB_MOD:active_recv(X).
-active_recv_bin(X) -> ?LIB_MOD:active_recv_bin(X).
-active_recv_chunk(X) -> ?LIB_MOD:active_recv_chunk(X).
-active_type(X) -> ?LIB_MOD:active_type(X).
-active_quote(X) -> ?LIB_MOD:active_quote(X).
-active_ip_v6_disabled(_X) -> {skipped,"unknown error"}.%%?LIB_MOD:active_ip_v6_disabled(X).
-progress_report_send(X) -> ?LIB_MOD:progress_report_send(X).
-progress_report_recv(X) -> ?LIB_MOD:progress_report_recv(X).
-
-fin(Config) ->
- ?LIB_MOD:ftpd_fin(Config).
diff --git a/lib/inets/test/ftp_macosx_x86_test.erl b/lib/inets/test/ftp_macosx_x86_test.erl
deleted file mode 100644
index 17b7160b95..0000000000
--- a/lib/inets/test/ftp_macosx_x86_test.erl
+++ /dev/null
@@ -1,159 +0,0 @@
-%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2005-2010. 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(ftp_macosx_x86_test).
-
--compile(export_all).
-
--include_lib("common_test/include/ct.hrl").
-
--define(LIB_MOD,ftp_suite_lib).
--define(CASE_WRAPPER(_A_,_B_,_C_),?LIB_MOD:wrapper(_A_,_B_,_C_)).
--define(PLATFORM,"Macosx x86 ").
-
-%% Test server callback functions
-%%--------------------------------------------------------------------
-%% 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) ->
- {File, NewFile} = ?LIB_MOD:test_filenames(),
- NewConfig = [{file, File}, {new_file, NewFile} | Config],
- ?LIB_MOD:ftpd_init(macosx_x86, NewConfig).
-
-%%--------------------------------------------------------------------
-%% 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) ->
- ?LIB_MOD:ftpd_fin(Config).
-
-%%--------------------------------------------------------------------
-%% Function: init_per_testcase(TestCase, 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.
-%% Description: Initiation before each test case
-%%--------------------------------------------------------------------
-init_per_testcase(Case, Config) ->
- ftp_suite_lib:init_per_testcase(Case, Config).
-%%--------------------------------------------------------------------
-%% Function: end_per_testcase(TestCase, 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) ->
- ftp_suite_lib:end_per_testcase(Case, Config).
-
-%%--------------------------------------------------------------------
-%% Function: all(Clause) -> TestCases
-%% Clause - atom() - suite | doc
-%% TestCases - [Case]
-%% Case - atom()
-%% Name of a test case.
-%% Description: Returns a list of all test cases in this test suite
-%%--------------------------------------------------------------------
-all() ->
-[open, open_port, {group, passive}, {group, active},
- api_missuse, not_owner, {group, progress_report}].
-
-groups() ->
- [{passive, [], ftp_suite_lib:passive(suite)},
- {active, [], ftp_suite_lib:active(suite)},
- {progress_report, [],
- ftp_suite_lib:progress_report(suite)}].
-
-init_per_group(_GroupName, Config) ->
- Config.
-
-end_per_group(_GroupName, Config) ->
- Config.
-
-
-%% Test cases starts here.
-%%--------------------------------------------------------------------
-open(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:open/1).
-open_port(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:open_port/1).
-api_missuse(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:api_missuse/1).
-not_owner(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:not_owner/1).
-
-passive_user(X) -> ?LIB_MOD:passive_user(X).
-passive_pwd(X) -> ?LIB_MOD:passive_pwd(X).
-passive_cd(X) -> ?LIB_MOD:passive_cd(X).
-passive_lcd(X) -> ?LIB_MOD:passive_lcd(X).
-passive_ls(X) -> ?LIB_MOD:passive_ls(X).
-passive_nlist(X) -> ?LIB_MOD:passive_nlist([{wildcard_support, false} | X]).
-passive_rename(X) -> ?LIB_MOD:passive_rename(X).
-passive_delete(X) -> ?LIB_MOD:passive_delete(X).
-passive_mkdir(X) -> ?LIB_MOD:passive_mkdir(X).
-passive_send(X) -> ?LIB_MOD:passive_send(X).
-passive_send_bin(X) -> ?LIB_MOD:passive_send_bin(X).
-passive_send_chunk(X) -> ?LIB_MOD:passive_send_chunk(X).
-passive_append(X) -> ?LIB_MOD:passive_append(X).
-passive_append_bin(X) -> ?LIB_MOD:passive_append_bin(X).
-passive_append_chunk(X) -> ?LIB_MOD:passive_append_chunk(X).
-passive_recv(X) -> ?LIB_MOD:passive_recv(X).
-passive_recv_bin(X) -> ?LIB_MOD:passive_recv_bin(X).
-passive_recv_chunk(X) -> ?LIB_MOD:passive_recv_chunk(X).
-passive_type(X) -> ?LIB_MOD:passive_type(X).
-passive_quote(X) -> ?LIB_MOD:passive_quote(X).
-passive_ip_v6_disabled(X) -> ?LIB_MOD:passive_ip_v6_disabled(X).
-active_user(X) -> ?LIB_MOD:active_user(X).
-active_pwd(X) -> ?LIB_MOD:active_pwd(X).
-active_cd(X) -> ?LIB_MOD:active_cd(X).
-active_lcd(X) -> ?LIB_MOD:active_lcd(X).
-active_ls(X) -> ?LIB_MOD:active_ls(X).
-active_nlist(X) -> ?LIB_MOD:active_nlist([{wildcard_support, false} | X]).
-active_rename(X) -> ?LIB_MOD:active_rename(X).
-active_delete(X) -> ?LIB_MOD:active_delete(X).
-active_mkdir(X) -> ?LIB_MOD:active_mkdir(X).
-active_send(X) -> ?LIB_MOD:active_send(X).
-active_send_bin(X) -> ?LIB_MOD:active_send_bin(X).
-active_send_chunk(X) -> ?LIB_MOD:active_send_chunk(X).
-active_append(X) -> ?LIB_MOD:active_append(X).
-active_append_bin(X) -> ?LIB_MOD:active_append_bin(X).
-active_append_chunk(X) -> ?LIB_MOD:active_append_chunk(X).
-active_recv(X) -> ?LIB_MOD:active_recv(X).
-active_recv_bin(X) -> ?LIB_MOD:active_recv_bin(X).
-active_recv_chunk(X) -> ?LIB_MOD:active_recv_chunk(X).
-active_type(X) -> ?LIB_MOD:active_type(X).
-active_quote(X) -> ?LIB_MOD:active_quote(X).
-active_ip_v6_disabled(X) -> ?LIB_MOD:active_ip_v6_disabled(X).
-progress_report_send(X) -> ?LIB_MOD:progress_report_send(X).
-progress_report_recv(X) -> ?LIB_MOD:progress_report_recv(X).
-
-fin(Config) ->
- ?LIB_MOD:ftpd_fin(Config).
diff --git a/lib/inets/test/ftp_netbsd_x86_test.erl b/lib/inets/test/ftp_netbsd_x86_test.erl
deleted file mode 100644
index bb474852c5..0000000000
--- a/lib/inets/test/ftp_netbsd_x86_test.erl
+++ /dev/null
@@ -1,159 +0,0 @@
-%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2005-2010. 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(ftp_netbsd_x86_test).
-
--compile(export_all).
-
--include_lib("common_test/include/ct.hrl").
-
--define(LIB_MOD,ftp_suite_lib).
--define(CASE_WRAPPER(_A_,_B_,_C_),?LIB_MOD:wrapper(_A_,_B_,_C_)).
--define(PLATFORM,"Netbsd x86 ").
-
-%% Test server callback functions
-%%--------------------------------------------------------------------
-%% 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) ->
- {File, NewFile} = ?LIB_MOD:test_filenames(),
- NewConfig = [{file, File}, {new_file, NewFile} | Config],
- ?LIB_MOD:ftpd_init(netbsd_x86, NewConfig).
-
-%%--------------------------------------------------------------------
-%% 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) ->
- ?LIB_MOD:ftpd_fin(Config).
-
-%%--------------------------------------------------------------------
-%% Function: init_per_testcase(TestCase, 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.
-%% Description: Initiation before each test case
-%%--------------------------------------------------------------------
-init_per_testcase(Case, Config) ->
- ftp_suite_lib:init_per_testcase(Case, Config).
-%%--------------------------------------------------------------------
-%% Function: end_per_testcase(TestCase, 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) ->
- ftp_suite_lib:end_per_testcase(Case, Config).
-
-%%--------------------------------------------------------------------
-%% Function: all(Clause) -> TestCases
-%% Clause - atom() - suite | doc
-%% TestCases - [Case]
-%% Case - atom()
-%% Name of a test case.
-%% Description: Returns a list of all test cases in this test suite
-%%--------------------------------------------------------------------
-all() ->
- [open, open_port, {group, passive}, {group, active},
- api_missuse, not_owner, {group, progress_report}].
-
-groups() ->
- [{passive, [], ftp_suite_lib:passive(suite)},
- {active, [], ftp_suite_lib:active(suite)},
- {progress_report, [],
- ftp_suite_lib:progress_report(suite)}].
-
-init_per_group(_GroupName, Config) ->
- Config.
-
-end_per_group(_GroupName, Config) ->
- Config.
-
-
-%% Test cases starts here.
-%%--------------------------------------------------------------------
-open(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:open/1).
-open_port(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:open_port/1).
-api_missuse(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:api_missuse/1).
-not_owner(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:not_owner/1).
-
-passive_user(X) -> ?LIB_MOD:passive_user(X).
-passive_pwd(X) -> ?LIB_MOD:passive_pwd(X).
-passive_cd(X) -> ?LIB_MOD:passive_cd(X).
-passive_lcd(X) -> ?LIB_MOD:passive_lcd(X).
-passive_ls(X) -> ?LIB_MOD:passive_ls(X).
-passive_nlist(X) -> ?LIB_MOD:passive_nlist(X).
-passive_rename(X) -> ?LIB_MOD:passive_rename(X).
-passive_delete(X) -> ?LIB_MOD:passive_delete(X).
-passive_mkdir(X) -> ?LIB_MOD:passive_mkdir(X).
-passive_send(X) -> ?LIB_MOD:passive_send(X).
-passive_send_bin(X) -> ?LIB_MOD:passive_send_bin(X).
-passive_send_chunk(X) -> ?LIB_MOD:passive_send_chunk(X).
-passive_append(X) -> ?LIB_MOD:passive_append(X).
-passive_append_bin(X) -> ?LIB_MOD:passive_append_bin(X).
-passive_append_chunk(X) -> ?LIB_MOD:passive_append_chunk(X).
-passive_recv(X) -> ?LIB_MOD:passive_recv(X).
-passive_recv_bin(X) -> ?LIB_MOD:passive_recv_bin(X).
-passive_recv_chunk(X) -> ?LIB_MOD:passive_recv_chunk(X).
-passive_type(X) -> ?LIB_MOD:passive_type(X).
-passive_quote(X) -> ?LIB_MOD:passive_quote(X).
-passive_ip_v6_disabled(X) -> ?LIB_MOD:passive_ip_v6_disabled(X).
-active_user(X) -> ?LIB_MOD:active_user(X).
-active_pwd(X) -> ?LIB_MOD:active_pwd(X).
-active_cd(X) -> ?LIB_MOD:active_cd(X).
-active_lcd(X) -> ?LIB_MOD:active_lcd(X).
-active_ls(X) -> ?LIB_MOD:active_ls(X).
-active_nlist(X) -> ?LIB_MOD:active_nlist(X).
-active_rename(X) -> ?LIB_MOD:active_rename(X).
-active_delete(X) -> ?LIB_MOD:active_delete(X).
-active_mkdir(X) -> ?LIB_MOD:active_mkdir(X).
-active_send(X) -> ?LIB_MOD:active_send(X).
-active_send_bin(X) -> ?LIB_MOD:active_send_bin(X).
-active_send_chunk(X) -> ?LIB_MOD:active_send_chunk(X).
-active_append(X) -> ?LIB_MOD:active_append(X).
-active_append_bin(X) -> ?LIB_MOD:active_append_bin(X).
-active_append_chunk(X) -> ?LIB_MOD:active_append_chunk(X).
-active_recv(X) -> ?LIB_MOD:active_recv(X).
-active_recv_bin(X) -> ?LIB_MOD:active_recv_bin(X).
-active_recv_chunk(X) -> ?LIB_MOD:active_recv_chunk(X).
-active_type(X) -> ?LIB_MOD:active_type(X).
-active_quote(X) -> ?LIB_MOD:active_quote(X).
-active_ip_v6_disabled(X) -> ?LIB_MOD:active_ip_v6_disabled(X).
-progress_report_send(X) -> ?LIB_MOD:progress_report_send(X).
-progress_report_recv(X) -> ?LIB_MOD:progress_report_recv(X).
-
-fin(Config) ->
- ?LIB_MOD:ftpd_fin(Config).
diff --git a/lib/inets/test/ftp_openbsd_x86_test.erl b/lib/inets/test/ftp_openbsd_x86_test.erl
deleted file mode 100644
index 54fce702a0..0000000000
--- a/lib/inets/test/ftp_openbsd_x86_test.erl
+++ /dev/null
@@ -1,158 +0,0 @@
-%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2005-2010. 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(ftp_openbsd_x86_test).
-
-%% Note: This directive should only be used in test suites.
--compile(export_all).
-
--include_lib("common_test/include/ct.hrl").
-
--define(LIB_MOD,ftp_suite_lib).
--define(CASE_WRAPPER(_A_,_B_,_C_),?LIB_MOD:wrapper(_A_,_B_,_C_)).
--define(PLATFORM,"Openbsd x86 ").
-
-%% Test server callback functions
-%%--------------------------------------------------------------------
-%% 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) ->
- {File, NewFile} = ?LIB_MOD:test_filenames(),
- NewConfig = [{file, File}, {new_file, NewFile} | Config],
- ?LIB_MOD:ftpd_init(openbsd_x86, NewConfig).
-
-%%--------------------------------------------------------------------
-%% 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) ->
- ?LIB_MOD:ftpd_fin(Config).
-
-%%--------------------------------------------------------------------
-%% Function: init_per_testcase(TestCase, 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.
-%% Description: Initiation before each test case
-%%--------------------------------------------------------------------
-init_per_testcase(Case, Config) ->
- ftp_suite_lib:init_per_testcase(Case, Config).
-%%--------------------------------------------------------------------
-%% Function: end_per_testcase(TestCase, 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) ->
- ftp_suite_lib:end_per_testcase(Case, Config).
-
-%%--------------------------------------------------------------------
-%% Function: all(Clause) -> TestCases
-%% Clause - atom() - suite | doc
-%% TestCases - [Case]
-%% Case - atom()
-%% Name of a test case.
-%% Description: Returns a list of all test cases in this test suite
-%%--------------------------------------------------------------------
-all() ->
- [open, open_port, {group, passive}, {group, active},
- api_missuse, not_owner, {group, progress_report}].
-
-groups() ->
- [{passive, [], ftp_suite_lib:passive(suite)},
- {active, [], ftp_suite_lib:active(suite)},
- {progress_report, [],
- ftp_suite_lib:progress_report(suite)}].
-
-init_per_group(_GroupName, Config) ->
- Config.
-
-end_per_group(_GroupName, Config) ->
- Config.
-
-
-%% Test cases starts here.
-%%--------------------------------------------------------------------
-
-open(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:open/1).
-open_port(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:open_port/1).
-api_missuse(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:api_missuse/1).
-not_owner(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:not_owner/1).
-
-passive_user(X) -> ?LIB_MOD:passive_user(X).
-passive_pwd(X) -> ?LIB_MOD:passive_pwd(X).
-passive_cd(X) -> ?LIB_MOD:passive_cd(X).
-passive_lcd(X) -> ?LIB_MOD:passive_lcd(X).
-passive_ls(X) -> ?LIB_MOD:passive_ls(X).
-passive_nlist(X) -> ?LIB_MOD:passive_nlist(X).
-passive_rename(X) -> ?LIB_MOD:passive_rename(X).
-passive_delete(X) -> ?LIB_MOD:passive_delete(X).
-passive_mkdir(X) -> ?LIB_MOD:passive_mkdir(X).
-passive_send(X) -> ?LIB_MOD:passive_send(X).
-passive_send_bin(X) -> ?LIB_MOD:passive_send_bin(X).
-passive_send_chunk(X) -> ?LIB_MOD:passive_send_chunk(X).
-passive_append(X) -> ?LIB_MOD:passive_append(X).
-passive_append_bin(X) -> ?LIB_MOD:passive_append_bin(X).
-passive_append_chunk(X) -> ?LIB_MOD:passive_append_chunk(X).
-passive_recv(X) -> ?LIB_MOD:passive_recv(X).
-passive_recv_bin(X) -> ?LIB_MOD:passive_recv_bin(X).
-passive_recv_chunk(X) -> ?LIB_MOD:passive_recv_chunk(X).
-passive_type(X) -> ?LIB_MOD:passive_type(X).
-passive_quote(X) -> ?LIB_MOD:passive_quote(X).
-passive_ip_v6_disabled(X) -> ?LIB_MOD:passive_ip_v6_disabled(X).
-active_user(X) -> ?LIB_MOD:active_user(X).
-active_pwd(X) -> ?LIB_MOD:active_pwd(X).
-active_cd(X) -> ?LIB_MOD:active_cd(X).
-active_lcd(X) -> ?LIB_MOD:active_lcd(X).
-active_ls(X) -> ?LIB_MOD:active_ls(X).
-active_nlist(X) -> ?LIB_MOD:active_nlist(X).
-active_rename(X) -> ?LIB_MOD:active_rename(X).
-active_delete(X) -> ?LIB_MOD:active_delete(X).
-active_mkdir(X) -> ?LIB_MOD:active_mkdir(X).
-active_send(X) -> ?LIB_MOD:active_send(X).
-active_send_bin(X) -> ?LIB_MOD:active_send_bin(X).
-active_send_chunk(X) -> ?LIB_MOD:active_send_chunk(X).
-active_append(X) -> ?LIB_MOD:active_append(X).
-active_append_bin(X) -> ?LIB_MOD:active_append_bin(X).
-active_append_chunk(X) -> ?LIB_MOD:active_append_chunk(X).
-active_recv(X) -> ?LIB_MOD:active_recv(X).
-active_recv_bin(X) -> ?LIB_MOD:active_recv_bin(X).
-active_recv_chunk(X) -> ?LIB_MOD:active_recv_chunk(X).
-active_type(X) -> ?LIB_MOD:active_type(X).
-active_quote(X) -> ?LIB_MOD:active_quote(X).
-active_ip_v6_disabled(X) -> ?LIB_MOD:active_ip_v6_disabled(X).
-progress_report_send(X) -> ?LIB_MOD:progress_report_send(X).
-progress_report_recv(X) -> ?LIB_MOD:progress_report_recv(X).
diff --git a/lib/inets/test/ftp_property_test_SUITE.erl b/lib/inets/test/ftp_property_test_SUITE.erl
new file mode 100644
index 0000000000..b314882296
--- /dev/null
+++ b/lib/inets/test/ftp_property_test_SUITE.erl
@@ -0,0 +1,53 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2004-2016. All Rights Reserved.
+%%
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
+%%
+%% http://www.apache.org/licenses/LICENSE-2.0
+%%
+%% Unless required by applicable law or agreed to in writing, software
+%% distributed under the License is distributed on an "AS IS" BASIS,
+%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+%% See the License for the specific language governing permissions and
+%% limitations under the License.
+%%
+%% %CopyrightEnd%
+%%
+%%
+
+%%% Run like this:
+%%% ct:run_test([{suite,"ftp_property_test_SUITE"}, {logdir,"/ldisk/OTP/LOG"}]).
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%%% %%%
+%%% WARNING %%%
+%%% %%%
+%%% This is experimental code which may be changed or removed %%%
+%%% anytime without any warning. %%%
+%%% %%%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+-module(ftp_property_test_SUITE).
+
+-compile(export_all).
+
+-include_lib("common_test/include/ct.hrl").
+
+all() -> [prop_ftp_case].
+
+
+init_per_suite(Config) ->
+ inets:start(),
+ ct_property_test:init_per_suite(Config).
+
+
+%%%---- test case
+prop_ftp_case(Config) ->
+ ct_property_test:quickcheck(
+ ftp_simple_client_server:prop_ftp(Config),
+ Config
+ ).
diff --git a/lib/inets/test/ftp_solaris10_sparc_test.erl b/lib/inets/test/ftp_solaris10_sparc_test.erl
deleted file mode 100644
index 0da50dc91b..0000000000
--- a/lib/inets/test/ftp_solaris10_sparc_test.erl
+++ /dev/null
@@ -1,161 +0,0 @@
-%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2005-2010. 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(ftp_solaris10_sparc_test).
-
--compile(export_all).
-
--include_lib("common_test/include/ct.hrl").
-
--define(LIB_MOD,ftp_suite_lib).
--define(CASE_WRAPPER(_A_,_B_,_C_),?LIB_MOD:wrapper(_A_,_B_,_C_)).
--define(PLATFORM,"Solaris 10 sparc ").
-
-
-%% Test server callback functions
-%%--------------------------------------------------------------------
-%% 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) ->
- {File, NewFile} = ?LIB_MOD:test_filenames(),
- NewConfig = [{file, File}, {new_file, NewFile} | Config],
- ?LIB_MOD:ftpd_init(solaris10_sparc, NewConfig).
-
-%%--------------------------------------------------------------------
-%% 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) ->
- ?LIB_MOD:ftpd_fin(Config).
-
-%%--------------------------------------------------------------------
-%% Function: init_per_testcase(TestCase, 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.
-%% Description: Initiation before each test case
-%%--------------------------------------------------------------------
-init_per_testcase(Case, Config) ->
- ftp_suite_lib:init_per_testcase(Case, Config).
-%%--------------------------------------------------------------------
-%% Function: end_per_testcase(TestCase, 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) ->
- ftp_suite_lib:end_per_testcase(Case, Config).
-
-%%--------------------------------------------------------------------
-%% Function: all(Clause) -> TestCases
-%% Clause - atom() - suite | doc
-%% TestCases - [Case]
-%% Case - atom()
-%% Name of a test case.
-%% Description: Returns a list of all test cases in this test suite
-%%--------------------------------------------------------------------
-all() ->
- [open, open_port, {group, passive}, {group, active},
- api_missuse, not_owner, {group, progress_report}].
-
-groups() ->
- [{passive, [], ftp_suite_lib:passive(suite)},
- {active, [], ftp_suite_lib:active(suite)},
- {progress_report, [],
- ftp_suite_lib:progress_report(suite)}].
-
-init_per_group(_GroupName, Config) ->
- Config.
-
-end_per_group(_GroupName, Config) ->
- Config.
-
-
-%% Test cases starts here.
-%%--------------------------------------------------------------------
-
-open(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:open/1).
-open_port(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:open_port/1).
-api_missuse(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:api_missuse/1).
-not_owner(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:not_owner/1).
-
-passive_user(X) -> ?LIB_MOD:passive_user(X).
-passive_pwd(X) -> ?LIB_MOD:passive_pwd(X).
-passive_cd(X) -> ?LIB_MOD:passive_cd(X).
-passive_lcd(X) -> ?LIB_MOD:passive_lcd(X).
-passive_ls(X) -> ?LIB_MOD:passive_ls(X).
-passive_nlist(X) -> ?LIB_MOD:passive_nlist(X).
-passive_rename(X) -> ?LIB_MOD:passive_rename(X).
-passive_delete(X) -> ?LIB_MOD:passive_delete(X).
-passive_mkdir(X) -> ?LIB_MOD:passive_mkdir(X).
-passive_send(X) -> ?LIB_MOD:passive_send(X).
-passive_send_bin(X) -> ?LIB_MOD:passive_send_bin(X).
-passive_send_chunk(X) -> ?LIB_MOD:passive_send_chunk(X).
-passive_append(X) -> ?LIB_MOD:passive_append(X).
-passive_append_bin(X) -> ?LIB_MOD:passive_append_bin(X).
-passive_append_chunk(X) -> ?LIB_MOD:passive_append_chunk(X).
-passive_recv(X) -> ?LIB_MOD:passive_recv(X).
-passive_recv_bin(X) -> ?LIB_MOD:passive_recv_bin(X).
-passive_recv_chunk(X) -> ?LIB_MOD:passive_recv_chunk(X).
-passive_type(X) -> ?LIB_MOD:passive_type(X).
-passive_quote(X) -> ?LIB_MOD:passive_quote(X).
-passive_ip_v6_disabled(X) -> ?LIB_MOD:passive_ip_v6_disabled(X).
-active_user(X) -> ?LIB_MOD:active_user(X).
-active_pwd(X) -> ?LIB_MOD:active_pwd(X).
-active_cd(X) -> ?LIB_MOD:active_cd(X).
-active_lcd(X) -> ?LIB_MOD:active_lcd(X).
-active_ls(X) -> ?LIB_MOD:active_ls(X).
-active_nlist(X) -> ?LIB_MOD:active_nlist(X).
-active_rename(X) -> ?LIB_MOD:active_rename(X).
-active_delete(X) -> ?LIB_MOD:active_delete(X).
-active_mkdir(X) -> ?LIB_MOD:active_mkdir(X).
-active_send(X) -> ?LIB_MOD:active_send(X).
-active_send_bin(X) -> ?LIB_MOD:active_send_bin(X).
-active_send_chunk(X) -> ?LIB_MOD:active_send_chunk(X).
-active_append(X) -> ?LIB_MOD:active_append(X).
-active_append_bin(X) -> ?LIB_MOD:active_append_bin(X).
-active_append_chunk(X) -> ?LIB_MOD:active_append_chunk(X).
-active_recv(X) -> ?LIB_MOD:active_recv(X).
-active_recv_bin(X) -> ?LIB_MOD:active_recv_bin(X).
-active_recv_chunk(X) -> ?LIB_MOD:active_recv_chunk(X).
-active_type(X) -> ?LIB_MOD:active_type(X).
-active_quote(X) -> ?LIB_MOD:active_quote(X).
-active_ip_v6_disabled(X) -> ?LIB_MOD:active_ip_v6_disabled(X).
-progress_report_send(X) -> ?LIB_MOD:progress_report_send(X).
-progress_report_recv(X) -> ?LIB_MOD:progress_report_recv(X).
-
-fin(Config) ->
- ?LIB_MOD:ftpd_fin(Config).
diff --git a/lib/inets/test/ftp_solaris10_x86_test.erl b/lib/inets/test/ftp_solaris10_x86_test.erl
deleted file mode 100644
index 3e7045bb4d..0000000000
--- a/lib/inets/test/ftp_solaris10_x86_test.erl
+++ /dev/null
@@ -1,162 +0,0 @@
-%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2010. 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(ftp_solaris10_x86_test).
-
--compile(export_all).
-
--include_lib("common_test/include/ct.hrl").
-
--define(LIB_MOD, ftp_suite_lib).
--define(CASE_WRAPPER(_A_,_B_,_C_), ?LIB_MOD:wrapper(_A_,_B_,_C_)).
--define(PLATFORM, "Solaris 10 x86 ").
-
-
-%% Test server callback functions
-%%--------------------------------------------------------------------
-%% 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) ->
- {File, NewFile} = ?LIB_MOD:test_filenames(),
- NewConfig = [{file, File}, {new_file, NewFile} | Config],
- ?LIB_MOD:ftpd_init(solaris10_x86, NewConfig).
-
-%%--------------------------------------------------------------------
-%% 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) ->
- ?LIB_MOD:ftpd_fin(Config).
-
-%%--------------------------------------------------------------------
-%% Function: init_per_testcase(TestCase, 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.
-%% Description: Initiation before each test case
-%%--------------------------------------------------------------------
-init_per_testcase(Case, Config) ->
- ftp_suite_lib:init_per_testcase(Case, Config).
-
-%%--------------------------------------------------------------------
-%% Function: end_per_testcase(TestCase, 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) ->
- ftp_suite_lib:end_per_testcase(Case, Config).
-
-%%--------------------------------------------------------------------
-%% Function: all(Clause) -> TestCases
-%% Clause - atom() - suite | doc
-%% TestCases - [Case]
-%% Case - atom()
-%% Name of a test case.
-%% Description: Returns a list of all test cases in this test suite
-%%--------------------------------------------------------------------
-all() ->
- [open, open_port, {group, passive}, {group, active},
- api_missuse, not_owner, {group, progress_report}].
-
-groups() ->
- [{passive, [], ftp_suite_lib:passive(suite)},
- {active, [], ftp_suite_lib:active(suite)},
- {progress_report, [],
- ftp_suite_lib:progress_report(suite)}].
-
-init_per_group(_GroupName, Config) ->
- Config.
-
-end_per_group(_GroupName, Config) ->
- Config.
-
-
-%% Test cases starts here.
-%%--------------------------------------------------------------------
-
-open(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:open/1).
-open_port(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:open_port/1).
-api_missuse(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:api_missuse/1).
-not_owner(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:not_owner/1).
-
-passive_user(X) -> ?LIB_MOD:passive_user(X).
-passive_pwd(X) -> ?LIB_MOD:passive_pwd(X).
-passive_cd(X) -> ?LIB_MOD:passive_cd(X).
-passive_lcd(X) -> ?LIB_MOD:passive_lcd(X).
-passive_ls(X) -> ?LIB_MOD:passive_ls(X).
-passive_nlist(X) -> ?LIB_MOD:passive_nlist(X).
-passive_rename(X) -> ?LIB_MOD:passive_rename(X).
-passive_delete(X) -> ?LIB_MOD:passive_delete(X).
-passive_mkdir(X) -> ?LIB_MOD:passive_mkdir(X).
-passive_send(X) -> ?LIB_MOD:passive_send(X).
-passive_send_bin(X) -> ?LIB_MOD:passive_send_bin(X).
-passive_send_chunk(X) -> ?LIB_MOD:passive_send_chunk(X).
-passive_append(X) -> ?LIB_MOD:passive_append(X).
-passive_append_bin(X) -> ?LIB_MOD:passive_append_bin(X).
-passive_append_chunk(X) -> ?LIB_MOD:passive_append_chunk(X).
-passive_recv(X) -> ?LIB_MOD:passive_recv(X).
-passive_recv_bin(X) -> ?LIB_MOD:passive_recv_bin(X).
-passive_recv_chunk(X) -> ?LIB_MOD:passive_recv_chunk(X).
-passive_type(X) -> ?LIB_MOD:passive_type(X).
-passive_quote(X) -> ?LIB_MOD:passive_quote(X).
-passive_ip_v6_disabled(X) -> ?LIB_MOD:passive_ip_v6_disabled(X).
-active_user(X) -> ?LIB_MOD:active_user(X).
-active_pwd(X) -> ?LIB_MOD:active_pwd(X).
-active_cd(X) -> ?LIB_MOD:active_cd(X).
-active_lcd(X) -> ?LIB_MOD:active_lcd(X).
-active_ls(X) -> ?LIB_MOD:active_ls(X).
-active_nlist(X) -> ?LIB_MOD:active_nlist(X).
-active_rename(X) -> ?LIB_MOD:active_rename(X).
-active_delete(X) -> ?LIB_MOD:active_delete(X).
-active_mkdir(X) -> ?LIB_MOD:active_mkdir(X).
-active_send(X) -> ?LIB_MOD:active_send(X).
-active_send_bin(X) -> ?LIB_MOD:active_send_bin(X).
-active_send_chunk(X) -> ?LIB_MOD:active_send_chunk(X).
-active_append(X) -> ?LIB_MOD:active_append(X).
-active_append_bin(X) -> ?LIB_MOD:active_append_bin(X).
-active_append_chunk(X) -> ?LIB_MOD:active_append_chunk(X).
-active_recv(X) -> ?LIB_MOD:active_recv(X).
-active_recv_bin(X) -> ?LIB_MOD:active_recv_bin(X).
-active_recv_chunk(X) -> ?LIB_MOD:active_recv_chunk(X).
-active_type(X) -> ?LIB_MOD:active_type(X).
-active_quote(X) -> ?LIB_MOD:active_quote(X).
-active_ip_v6_disabled(X) -> ?LIB_MOD:active_ip_v6_disabled(X).
-progress_report_send(X) -> ?LIB_MOD:progress_report_send(X).
-progress_report_recv(X) -> ?LIB_MOD:progress_report_recv(X).
-
-fin(Config) ->
- ?LIB_MOD:ftpd_fin(Config).
diff --git a/lib/inets/test/ftp_solaris8_sparc_test.erl b/lib/inets/test/ftp_solaris8_sparc_test.erl
deleted file mode 100644
index 23dbfc8fe3..0000000000
--- a/lib/inets/test/ftp_solaris8_sparc_test.erl
+++ /dev/null
@@ -1,159 +0,0 @@
-%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2005-2010. 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(ftp_solaris8_sparc_test).
-
--compile(export_all).
-
--include_lib("common_test/include/ct.hrl").
-
--define(LIB_MOD,ftp_suite_lib).
--define(CASE_WRAPPER(_A_,_B_,_C_),?LIB_MOD:wrapper(_A_,_B_,_C_)).
--define(PLATFORM,"Solaris 8 sparc ").
-
-%% Test server callback functions
-%%--------------------------------------------------------------------
-%% 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) ->
- {File, NewFile} = ?LIB_MOD:test_filenames(),
- NewConfig = [{file, File}, {new_file, NewFile} | Config],
- ?LIB_MOD:ftpd_init(solaris8_sparc, NewConfig).
-
-%%--------------------------------------------------------------------
-%% 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) ->
- ?LIB_MOD:ftpd_fin(Config).
-
-%%--------------------------------------------------------------------
-%% Function: init_per_testcase(TestCase, 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.
-%% Description: Initiation before each test case
-%%--------------------------------------------------------------------
-init_per_testcase(Case, Config) ->
- ftp_suite_lib:init_per_testcase(Case, Config).
-%%--------------------------------------------------------------------
-%% Function: end_per_testcase(TestCase, 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) ->
- ftp_suite_lib:end_per_testcase(Case, Config).
-
-%%--------------------------------------------------------------------
-%% Function: all(Clause) -> TestCases
-%% Clause - atom() - suite | doc
-%% TestCases - [Case]
-%% Case - atom()
-%% Name of a test case.
-%% Description: Returns a list of all test cases in this test suite
-%%--------------------------------------------------------------------
-all() ->
- [open, open_port, {group, passive}, {group, active},
- api_missuse, not_owner, {group, progress_report}].
-
-groups() ->
- [{passive, [], ftp_suite_lib:passive(suite)},
- {active, [], ftp_suite_lib:active(suite)},
- {progress_report, [],
- ftp_suite_lib:progress_report(suite)}].
-
-init_per_group(_GroupName, Config) ->
- Config.
-
-end_per_group(_GroupName, Config) ->
- Config.
-
-
-%% Test cases starts here.
-
-open(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:open/1).
-open_port(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:open_port/1).
-api_missuse(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:api_missuse/1).
-not_owner(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:not_owner/1).
-
-passive_user(X) -> ?LIB_MOD:passive_user(X).
-passive_pwd(X) -> ?LIB_MOD:passive_pwd(X).
-passive_cd(X) -> ?LIB_MOD:passive_cd(X).
-passive_lcd(X) -> ?LIB_MOD:passive_lcd(X).
-passive_ls(X) -> ?LIB_MOD:passive_ls(X).
-passive_nlist(X) -> ?LIB_MOD:passive_nlist(X).
-passive_rename(X) -> ?LIB_MOD:passive_rename(X).
-passive_delete(X) -> ?LIB_MOD:passive_delete(X).
-passive_mkdir(X) -> ?LIB_MOD:passive_mkdir(X).
-passive_send(X) -> ?LIB_MOD:passive_send(X).
-passive_send_bin(X) -> ?LIB_MOD:passive_send_bin(X).
-passive_send_chunk(X) -> ?LIB_MOD:passive_send_chunk(X).
-passive_append(X) -> ?LIB_MOD:passive_append(X).
-passive_append_bin(X) -> ?LIB_MOD:passive_append_bin(X).
-passive_append_chunk(X) -> ?LIB_MOD:passive_append_chunk(X).
-passive_recv(X) -> ?LIB_MOD:passive_recv(X).
-passive_recv_bin(X) -> ?LIB_MOD:passive_recv_bin(X).
-passive_recv_chunk(X) -> ?LIB_MOD:passive_recv_chunk(X).
-passive_type(X) -> ?LIB_MOD:passive_type(X).
-passive_quote(X) -> ?LIB_MOD:passive_quote(X).
-passive_ip_v6_disabled(X) -> ?LIB_MOD:passive_ip_v6_disabled(X).
-active_user(X) -> ?LIB_MOD:active_user(X).
-active_pwd(X) -> ?LIB_MOD:active_pwd(X).
-active_cd(X) -> ?LIB_MOD:active_cd(X).
-active_lcd(X) -> ?LIB_MOD:active_lcd(X).
-active_ls(X) -> ?LIB_MOD:active_ls(X).
-active_nlist(X) -> ?LIB_MOD:active_nlist(X).
-active_rename(X) -> ?LIB_MOD:active_rename(X).
-active_delete(X) -> ?LIB_MOD:active_delete(X).
-active_mkdir(X) -> ?LIB_MOD:active_mkdir(X).
-active_send(X) -> ?LIB_MOD:active_send(X).
-active_send_bin(X) -> ?LIB_MOD:active_send_bin(X).
-active_send_chunk(X) -> ?LIB_MOD:active_send_chunk(X).
-active_append(X) -> ?LIB_MOD:active_append(X).
-active_append_bin(X) -> ?LIB_MOD:active_append_bin(X).
-active_append_chunk(X) -> ?LIB_MOD:active_append_chunk(X).
-active_recv(X) -> ?LIB_MOD:active_recv(X).
-active_recv_bin(X) -> ?LIB_MOD:active_recv_bin(X).
-active_recv_chunk(X) -> ?LIB_MOD:active_recv_chunk(X).
-active_type(X) -> ?LIB_MOD:active_type(X).
-active_quote(X) -> ?LIB_MOD:active_quote(X).
-active_ip_v6_disabled(X) -> ?LIB_MOD:active_ip_v6_disabled(X).
-progress_report_send(X) -> ?LIB_MOD:progress_report_send(X).
-progress_report_recv(X) -> ?LIB_MOD:progress_report_recv(X).
-
-fin(Config) ->
- ?LIB_MOD:ftpd_fin(Config).
diff --git a/lib/inets/test/ftp_solaris9_sparc_test.erl b/lib/inets/test/ftp_solaris9_sparc_test.erl
deleted file mode 100644
index 896e2f497f..0000000000
--- a/lib/inets/test/ftp_solaris9_sparc_test.erl
+++ /dev/null
@@ -1,158 +0,0 @@
-%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2005-2010. 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(ftp_solaris9_sparc_test).
-
--compile(export_all).
-
--include_lib("common_test/include/ct.hrl").
-
--define(LIB_MOD,ftp_suite_lib).
--define(CASE_WRAPPER(_A_,_B_,_C_),?LIB_MOD:wrapper(_A_,_B_,_C_)).
--define(PLATFORM,"Solaris 9 sparc ").
-%% Test server callback functions
-%%--------------------------------------------------------------------
-%% 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) ->
- {File, NewFile} = ?LIB_MOD:test_filenames(),
- NewConfig = [{file, File}, {new_file, NewFile} | Config],
- ?LIB_MOD:ftpd_init(solaris9_sparc, NewConfig).
-
-%%--------------------------------------------------------------------
-%% 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) ->
- ?LIB_MOD:ftpd_fin(Config).
-
-%%--------------------------------------------------------------------
-%% Function: init_per_testcase(TestCase, 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.
-%% Description: Initiation before each test case
-%%--------------------------------------------------------------------
-init_per_testcase(Case, Config) ->
- ftp_suite_lib:init_per_testcase(Case, Config).
-%%--------------------------------------------------------------------
-%% Function: end_per_testcase(TestCase, 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) ->
- ftp_suite_lib:end_per_testcase(Case, Config).
-
-%%--------------------------------------------------------------------
-%% Function: all(Clause) -> TestCases
-%% Clause - atom() - suite | doc
-%% TestCases - [Case]
-%% Case - atom()
-%% Name of a test case.
-%% Description: Returns a list of all test cases in this test suite
-%%--------------------------------------------------------------------
-all() ->
- [open, open_port, {group, passive}, {group, active},
- api_missuse, not_owner, {group, progress_report}].
-
-groups() ->
- [{passive, [], ftp_suite_lib:passive(suite)},
- {active, [], ftp_suite_lib:active(suite)},
- {progress_report, [],
- ftp_suite_lib:progress_report(suite)}].
-
-init_per_group(_GroupName, Config) ->
- Config.
-
-end_per_group(_GroupName, Config) ->
- Config.
-
-
-%% Test cases starts here.
-
-open(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:open/1).
-open_port(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:open_port/1).
-api_missuse(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:api_missuse/1).
-not_owner(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:not_owner/1).
-
-passive_user(X) -> ?LIB_MOD:passive_user(X).
-passive_pwd(X) -> ?LIB_MOD:passive_pwd(X).
-passive_cd(X) -> ?LIB_MOD:passive_cd(X).
-passive_lcd(X) -> ?LIB_MOD:passive_lcd(X).
-passive_ls(X) -> ?LIB_MOD:passive_ls(X).
-passive_nlist(X) -> ?LIB_MOD:passive_nlist(X).
-passive_rename(X) -> ?LIB_MOD:passive_rename(X).
-passive_delete(X) -> ?LIB_MOD:passive_delete(X).
-passive_mkdir(X) -> ?LIB_MOD:passive_mkdir(X).
-passive_send(X) -> ?LIB_MOD:passive_send(X).
-passive_send_bin(X) -> ?LIB_MOD:passive_send_bin(X).
-passive_send_chunk(X) -> ?LIB_MOD:passive_send_chunk(X).
-passive_append(X) -> ?LIB_MOD:passive_append(X).
-passive_append_bin(X) -> ?LIB_MOD:passive_append_bin(X).
-passive_append_chunk(X) -> ?LIB_MOD:passive_append_chunk(X).
-passive_recv(X) -> ?LIB_MOD:passive_recv(X).
-passive_recv_bin(X) -> ?LIB_MOD:passive_recv_bin(X).
-passive_recv_chunk(X) -> ?LIB_MOD:passive_recv_chunk(X).
-passive_type(X) -> ?LIB_MOD:passive_type(X).
-passive_quote(X) -> ?LIB_MOD:passive_quote(X).
-passive_ip_v6_disabled(X) -> ?LIB_MOD:passive_ip_v6_disabled(X).
-active_user(X) -> ?LIB_MOD:active_user(X).
-active_pwd(X) -> ?LIB_MOD:active_pwd(X).
-active_cd(X) -> ?LIB_MOD:active_cd(X).
-active_lcd(X) -> ?LIB_MOD:active_lcd(X).
-active_ls(X) -> ?LIB_MOD:active_ls(X).
-active_nlist(X) -> ?LIB_MOD:active_nlist(X).
-active_rename(X) -> ?LIB_MOD:active_rename(X).
-active_delete(X) -> ?LIB_MOD:active_delete(X).
-active_mkdir(X) -> ?LIB_MOD:active_mkdir(X).
-active_send(X) -> ?LIB_MOD:active_send(X).
-active_send_bin(X) -> ?LIB_MOD:active_send_bin(X).
-active_send_chunk(X) -> ?LIB_MOD:active_send_chunk(X).
-active_append(X) -> ?LIB_MOD:active_append(X).
-active_append_bin(X) -> ?LIB_MOD:active_append_bin(X).
-active_append_chunk(X) -> ?LIB_MOD:active_append_chunk(X).
-active_recv(X) -> ?LIB_MOD:active_recv(X).
-active_recv_bin(X) -> ?LIB_MOD:active_recv_bin(X).
-active_recv_chunk(X) -> ?LIB_MOD:active_recv_chunk(X).
-active_type(X) -> ?LIB_MOD:active_type(X).
-active_quote(X) -> ?LIB_MOD:active_quote(X).
-active_ip_v6_disabled(X) -> ?LIB_MOD:active_ip_v6_disabled(X).
-progress_report_send(X) -> ?LIB_MOD:progress_report_send(X).
-progress_report_recv(X) -> ?LIB_MOD:progress_report_recv(X).
-
-fin(Config) ->
- ?LIB_MOD:ftpd_fin(Config).
diff --git a/lib/inets/test/ftp_suite_lib.erl b/lib/inets/test/ftp_suite_lib.erl
deleted file mode 100644
index 35f21cc74d..0000000000
--- a/lib/inets/test/ftp_suite_lib.erl
+++ /dev/null
@@ -1,1675 +0,0 @@
-%%
-%% %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(ftp_suite_lib).
-
-
--include_lib("test_server/include/test_server.hrl").
--include_lib("test_server/include/test_server_line.hrl").
--include("inets_test_lib.hrl").
-
-%% Test server specific exports
-% -export([init_per_testcase/2, end_per_testcase/2]).
-
--compile(export_all).
-
-
--record(progress, {
- current = 0,
- total
- }).
-
-
-
--define(FTP_USER, "anonymous").
--define(FTP_PASS, passwd()).
--define(FTP_PORT, 21).
-
--define(BAD_HOST, "badhostname").
--define(BAD_USER, "baduser").
--define(BAD_DIR, "baddirectory").
-
--ifdef(ftp_debug_client).
--define(ftp_open(Host, Flags),
- do_ftp_open(Host, [{debug, debug},
- {timeout, timer:seconds(15)} | Flags])).
--else.
--ifdef(ftp_trace_client).
--define(ftp_open(Host, Flags),
- do_ftp_open(Host, [{debug, trace},
- {timeout, timer:seconds(15)} | Flags])).
--else.
--define(ftp_open(Host, Flags),
- do_ftp_open(Host, [{verbose, true},
- {timeout, timer:seconds(15)} | Flags])).
--endif.
--endif.
-
-%% -- Tickets --
-
-tickets(doc) ->
- "Test cases for reported bugs";
-tickets(suite) ->
- [ticket_6035].
-
-%% --
-
-ftpd_init(FtpdTag, Config) ->
- %% Get the host name(s) of FTP server
- Hosts =
- case ct:get_config(ftpd_hosts) of
- undefined ->
- ftpd_hosts(data_dir(Config));
- H ->
- H
- end,
- p("ftpd_init -> "
- "~n Hosts: ~p"
- "~n Config: ~p"
- "~n FtpdTag: ~p", [Hosts, Config, FtpdTag]),
- %% Get the first host that actually have a running FTP server
- case lists:keysearch(FtpdTag, 1, Hosts) of
- {value, {_, TagHosts}} when is_list(TagHosts) ->
- inets:start(),
- case (catch get_ftpd_host(TagHosts)) of
- {ok, Host} ->
- inets:stop(),
- [{ftp_remote_host, Host}|Config];
- _ ->
- inets:stop(),
- Reason = lists:flatten(
- io_lib:format("Could not find a valid "
- "FTP server for ~p (~p)",
- [FtpdTag, TagHosts])),
- {skip, Reason}
- end;
- _ ->
- Reason = lists:flatten(
- io_lib:format("No host(s) running FTPD server "
- "for ~p", [FtpdTag])),
- {skip, Reason}
- end.
-
-ftpd_fin(Config) ->
- lists:keydelete(ftp_remote_host, 1, Config).
-
-get_ftpd_host([]) ->
- {error, no_host};
-get_ftpd_host([Host|Hosts]) ->
- p("get_ftpd_host -> entry with"
- "~n Host: ~p"
- "~n", [Host]),
- case (catch ftp:open(Host, [{port, ?FTP_PORT}, {timeout, 20000}])) of
- {ok, Pid} ->
- (catch ftp:close(Pid)),
- {ok, Host};
- _ ->
- get_ftpd_host(Hosts)
- end.
-
-
-%%--------------------------------------------------------------------
-
-dirty_select_ftpd_host(Config) ->
- Hosts =
- case ct:get_config(ftpd_hosts) of
- undefined ->
- ftpd_hosts(data_dir(Config));
- H ->
- H
- end,
- dirty_select_ftpd_host2(Hosts).
-
-dirty_select_ftpd_host2([]) ->
- throw({error, not_found});
-dirty_select_ftpd_host2([{PlatformTag, Hosts} | PlatformHosts]) ->
- case dirty_select_ftpd_host3(Hosts) of
- none ->
- dirty_select_ftpd_host2(PlatformHosts);
- {ok, Host} ->
- {PlatformTag, Host}
- end.
-
-dirty_select_ftpd_host3([]) ->
- none;
-dirty_select_ftpd_host3([Host|Hosts]) when is_list(Host) ->
- case dirty_select_ftpd_host4(Host) of
- true ->
- {ok, Host};
- false ->
- dirty_select_ftpd_host3(Hosts)
- end;
-dirty_select_ftpd_host3([_|Hosts]) ->
- dirty_select_ftpd_host3(Hosts).
-
-%% This is a very simple and dirty test that there is a
-%% (FTP) deamon on the other end.
-dirty_select_ftpd_host4(Host) ->
- Port = 21,
- IpFam = inet,
- Opts = [IpFam, binary, {packet, 0}, {active, false}],
- Timeout = ?SECS(5),
- case gen_tcp:connect(Host, Port, Opts, Timeout) of
- {ok, Sock} ->
- gen_tcp:close(Sock),
- true;
- _Error ->
- false
- end.
-
-
-%%--------------------------------------------------------------------
-
-test_filenames() ->
- {ok, Host} = inet:gethostname(),
- File = Host ++ "_ftp_test.txt",
- NewFile = "new_" ++ File,
- {File, NewFile}.
-
-%%--------------------------------------------------------------------
-%% 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)
- when (Case =:= open) orelse
- (Case =:= open_port) ->
- put(ftp_testcase, Case),
- io:format(user, "~n~n*** INIT ~w:~w ***~n~n", [?MODULE, Case]),
- inets:start(),
- NewConfig = data_dir(Config),
- watch_dog(NewConfig);
-
-init_per_testcase(Case, Config) ->
- put(ftp_testcase, Case),
- do_init_per_testcase(Case, Config).
-
-do_init_per_testcase(Case, Config)
- when (Case =:= passive_user) ->
- io:format(user, "~n~n*** INIT ~w:~w ***~n~n", [?MODULE,Case]),
- inets:start(),
- NewConfig = close_connection(watch_dog(Config)),
- Host = ftp_host(Config),
- case (catch ?ftp_open(Host, [{mode, passive}])) of
- {ok, Pid} ->
- [{ftp, Pid} | data_dir(NewConfig)];
- {skip, _} = SKIP ->
- SKIP
- end;
-
-do_init_per_testcase(Case, Config)
- when (Case =:= active_user) ->
- io:format(user, "~n~n*** INIT ~w:~w ***~n~n", [?MODULE, Case]),
- inets:start(),
- NewConfig = close_connection(watch_dog(Config)),
- Host = ftp_host(Config),
- case (catch ?ftp_open(Host, [{mode, active}])) of
- {ok, Pid} ->
- [{ftp, Pid} | data_dir(NewConfig)];
- {skip, _} = SKIP ->
- SKIP
- end;
-
-do_init_per_testcase(Case, Config)
- when (Case =:= progress_report_send) orelse
- (Case =:= progress_report_recv) ->
- inets:start(),
- io:format(user, "~n~n*** INIT ~w:~w ***~n~n", [?MODULE, Case]),
- NewConfig = close_connection(watch_dog(Config)),
- Host = ftp_host(Config),
- Opts = [{port, ?FTP_PORT},
- {verbose, true},
- {progress, {?MODULE, progress, #progress{}}}],
- case ftp:open(Host, Opts) of
- {ok, Pid} ->
- ok = ftp:user(Pid, ?FTP_USER, ?FTP_PASS),
- [{ftp, Pid} | data_dir(NewConfig)];
- {skip, _} = SKIP ->
- SKIP
- end;
-
-do_init_per_testcase(Case, Config) ->
- io:format(user,"~n~n*** INIT ~w:~w ***~n~n", [?MODULE, Case]),
- inets:start(),
- NewConfig = close_connection(watch_dog(Config)),
- Host = ftp_host(Config),
- Opts1 =
- if
- ((Case =:= passive_ip_v6_disabled) orelse
- (Case =:= active_ip_v6_disabled)) ->
- [{ipfamily, inet}];
- true ->
- []
- end,
- Opts2 =
- case string:tokens(atom_to_list(Case), [$_]) of
- ["active" | _] ->
- [{mode, active} | Opts1];
- _ ->
- [{mode, passive} | Opts1]
- end,
- case (catch ?ftp_open(Host, Opts2)) of
- {ok, Pid} ->
- ok = ftp:user(Pid, ?FTP_USER, ?FTP_PASS),
- [{ftp, Pid} | data_dir(NewConfig)];
- {skip, _} = SKIP ->
- SKIP
- end.
-
-
-%%--------------------------------------------------------------------
-%% 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(_, Config) ->
- NewConfig = close_connection(Config),
- Dog = ?config(watchdog, NewConfig),
- inets:stop(),
- test_server:timetrap_cancel(Dog),
- ok.
-
-
-%%-------------------------------------------------------------------------
-%% Suites similar for all hosts.
-%%-------------------------------------------------------------------------
-
-passive(suite) ->
- [
- passive_user,
- passive_pwd,
- passive_cd,
- passive_lcd,
- passive_ls,
- passive_nlist,
- passive_rename,
- passive_delete,
- passive_mkdir,
- passive_send,
- passive_send_bin,
- passive_send_chunk,
- passive_append,
- passive_append_bin,
- passive_append_chunk,
- passive_recv,
- passive_recv_bin,
- passive_recv_chunk,
- passive_type,
- passive_quote,
- passive_ip_v6_disabled
- ].
-
-active(suite) ->
- [
- active_user,
- active_pwd,
- active_cd,
- active_lcd,
- active_ls,
- active_nlist,
- active_rename,
- active_delete,
- active_mkdir,
- active_send,
- active_send_bin,
- active_send_chunk,
- active_append,
- active_append_bin,
- active_append_chunk,
- active_recv,
- active_recv_bin,
- active_recv_chunk,
- active_type,
- active_quote,
- active_ip_v6_disabled
- ].
-
-
-
-%%-------------------------------------------------------------------------
-%% Test cases starts here.
-%%-------------------------------------------------------------------------
-
-open(doc) ->
- ["Open an ftp connection to a host and close the connection."
- "Also check that !-messages does not disturbe the connection"];
-open(suite) ->
- [];
-open(Config) when is_list(Config) ->
- Host = ftp_host(Config),
- (catch tc_open(Host)).
-
-
-tc_open(Host) ->
- p("tc_open -> entry with"
- "~n Host: ~p", [Host]),
- {ok, Pid} = ?ftp_open(Host, []),
- ok = ftp:close(Pid),
- p("tc_open -> try (ok) open 1"),
- {ok, Pid1} =
- ftp:open({option_list, [{host,Host},
- {port, ?FTP_PORT},
- {flags, [verbose]},
- {timeout, 30000}]}),
- ok = ftp:close(Pid1),
-
- p("tc_open -> try (fail) open 2"),
- {error, ehost} =
- ftp:open({option_list, [{port, ?FTP_PORT}, {flags, [verbose]}]}),
- {ok, Pid2} = ftp:open(Host),
- ok = ftp:close(Pid2),
-
- p("tc_open -> try (ok) open 3"),
- {ok, NewHost} = inet:getaddr(Host, inet),
- {ok, Pid3} = ftp:open(NewHost),
- ftp:user(Pid3, ?FTP_USER, ?FTP_PASS),
- Pid3 ! foobar,
- test_server:sleep(5000),
- {message_queue_len, 0} = process_info(self(), message_queue_len),
- ["200" ++ _] = ftp:quote(Pid3, "NOOP"),
- ok = ftp:close(Pid3),
-
- %% Bad input that has default values are ignored and the defult
- %% is used.
- p("tc_open -> try (ok) open 4"),
- {ok, Pid4} =
- ftp:open({option_list, [{host, Host},
- {port, badarg},
- {flags, [verbose]},
- {timeout, 30000}]}),
- test_server:sleep(100),
- ok = ftp:close(Pid4),
-
- p("tc_open -> try (ok) open 5"),
- {ok, Pid5} =
- ftp:open({option_list, [{host, Host},
- {port, ?FTP_PORT},
- {flags, [verbose]},
- {timeout, -42}]}),
- test_server:sleep(100),
- ok = ftp:close(Pid5),
-
- p("tc_open -> try (ok) open 6"),
- {ok, Pid6} =
- ftp:open({option_list, [{host, Host},
- {port, ?FTP_PORT},
- {flags, [verbose]},
- {mode, cool}]}),
- test_server:sleep(100),
- ok = ftp:close(Pid6),
-
- p("tc_open -> try (ok) open 7"),
- {ok, Pid7} =
- ftp:open(Host, [{port, ?FTP_PORT}, {verbose, true}, {timeout, 30000}]),
- ok = ftp:close(Pid7),
-
- p("tc_open -> try (ok) open 8"),
- {ok, Pid8} =
- ftp:open(Host, ?FTP_PORT),
- ok = ftp:close(Pid8),
-
- p("tc_open -> try (ok) open 9"),
- {ok, Pid9} =
- ftp:open(Host, [{port, ?FTP_PORT},
- {verbose, true},
- {timeout, 30000},
- {dtimeout, -99}]),
- ok = ftp:close(Pid9),
-
- p("tc_open -> try (ok) open 10"),
- {ok, Pid10} =
- ftp:open(Host, [{port, ?FTP_PORT},
- {verbose, true},
- {timeout, 30000},
- {dtimeout, "foobar"}]),
- ok = ftp:close(Pid10),
-
- p("tc_open -> try (ok) open 11"),
- {ok, Pid11} =
- ftp:open(Host, [{port, ?FTP_PORT},
- {verbose, true},
- {timeout, 30000},
- {dtimeout, 1}]),
- ok = ftp:close(Pid11),
-
- p("tc_open -> done"),
- ok.
-
-
-%%-------------------------------------------------------------------------
-
-open_port(doc) ->
- ["Open an ftp connection to a host with given port number "
- "and close the connection."]; % See also OTP-3892
-open_port(suite) ->
- [];
-open_port(Config) when is_list(Config) ->
- Host = ftp_host(Config),
- {ok, Pid} = ftp:open(Host, [{port, ?FTP_PORT}]),
- ok = ftp:close(Pid),
- {error, ehost} = ftp:open(?BAD_HOST, []),
- ok.
-
-
-%%-------------------------------------------------------------------------
-
-passive_user(doc) ->
- ["Open an ftp connection to a host, and logon as anonymous ftp."];
-passive_user(suite) ->
- [];
-passive_user(Config) when is_list(Config) ->
- Pid = ?config(ftp, Config),
- p("Pid: ~p",[Pid]),
- do_user(Pid).
-
-
-%%-------------------------------------------------------------------------
-
-passive_pwd(doc) ->
- ["Test ftp:pwd/1 & ftp:lpwd/1"];
-passive_pwd(suite) ->
- [];
-passive_pwd(Config) when is_list(Config) ->
- Pid = ?config(ftp, Config),
- do_pwd(Pid).
-
-
-%%-------------------------------------------------------------------------
-
-passive_cd(doc) ->
- ["Open an ftp connection, log on as anonymous ftp, and cd to the"
- "directory \"/pub\" and the to the non-existent directory."];
-passive_cd(suite) ->
- [];
-passive_cd(Config) when is_list(Config) ->
- Pid = ?config(ftp, Config),
- do_cd(Pid).
-
-
-%%-------------------------------------------------------------------------
-
-passive_lcd(doc) ->
- ["Test api function ftp:lcd/2"];
-passive_lcd(suite) ->
- [];
-passive_lcd(Config) when is_list(Config) ->
- Pid = ?config(ftp, Config),
- PrivDir = ?config(priv_dir, Config),
- do_lcd(Pid, PrivDir).
-
-
-%%-------------------------------------------------------------------------
-
-passive_ls(doc) ->
- ["Open an ftp connection; ls the current directory, and the "
- "\"incoming\" directory. We assume that ls never fails, since "
- "it's output is meant to be read by humans. "];
-passive_ls(suite) ->
- [];
-passive_ls(Config) when is_list(Config) ->
- Pid = ?config(ftp, Config),
- do_ls(Pid).
-
-
-%%-------------------------------------------------------------------------
-
-passive_nlist(doc) ->
- ["Open an ftp connection; nlist the current directory, and the "
- "\"incoming\" directory. Nlist does not behave consistenly over "
- "operating systems. On some it is an error to have an empty "
- "directory."];
-passive_nlist(suite) ->
- [];
-passive_nlist(Config) when is_list(Config) ->
- Pid = ?config(ftp, Config),
- WildcardSupport = ?config(wildcard_support, Config),
- do_nlist(Pid, WildcardSupport).
-
-
-%%-------------------------------------------------------------------------
-
-passive_rename(doc) ->
- ["Transfer a file to the server, and rename it; then remove it."];
-passive_rename(suite) ->
- [];
-passive_rename(Config) when is_list(Config) ->
- Pid = ?config(ftp, Config),
- do_rename(Pid, Config).
-
-
-%%-------------------------------------------------------------------------
-
-passive_delete(doc) ->
- ["Transfer a file to the server, and then delete it"];
-passive_delete(suite) ->
- [];
-passive_delete(Config) when is_list(Config) ->
- Pid = ?config(ftp, Config),
- do_delete(Pid, Config).
-
-
-%%-------------------------------------------------------------------------
-
-passive_mkdir(doc) ->
- ["Make a remote directory, cd to it, go to parent directory, and "
- "remove the directory."];
-passive_mkdir(suite) ->
- [];
-passive_mkdir(Config) when is_list(Config) ->
- Pid = ?config(ftp, Config),
- do_mkdir(Pid).
-
-
-%%-------------------------------------------------------------------------
-
-passive_send(doc) ->
- ["Create a local file in priv_dir; open an ftp connection to a host; "
- "logon as anonymous ftp; cd to the directory \"incoming\"; lcd to "
- "priv_dir; send the file; get a directory listing and check that "
- "the file is on the list;, delete the remote file; get another listing "
- "and check that the file is not on the list; close the session; "
- "delete the local file."];
-passive_send(suite) ->
- [];
-passive_send(Config) when is_list(Config) ->
- Pid = ?config(ftp, Config),
- do_send(Pid, Config).
-
-
-%%-------------------------------------------------------------------------
-
-passive_append(doc) ->
- ["Create a local file in priv_dir; open an ftp connection to a host; "
- "logon as anonymous ftp; cd to the directory \"incoming\"; lcd to "
- "priv_dir; append the file to a file at the remote side that not exits"
- "this will create the file at the remote side. Then it append the file "
- "again. When this is done it recive the remote file and control that"
- "the content is doubled in it.After that it will remove the files"];
-passive_append(suite) ->
- [];
-passive_append(Config) when is_list(Config) ->
- Pid = ?config(ftp, Config),
- do_append(Pid, Config).
-
-
-%%-------------------------------------------------------------------------
-
-passive_send_bin(doc) ->
- ["Open a connection to a host; cd to the directory \"incoming\"; "
- "send a binary; remove file; close the connection."];
-passive_send_bin(suite) ->
- [];
-passive_send_bin(Config) when is_list(Config) ->
- Pid = ?config(ftp, Config),
- do_send_bin(Pid, Config).
-
-%%-------------------------------------------------------------------------
-
-passive_append_bin(doc) ->
- ["Open a connection to a host; cd to the directory \"incoming\"; "
- "append a binary twice; get the file and compare the content"
- "remove file; close the connection."];
-passive_append_bin(suite) ->
- [];
-passive_append_bin(Config) when is_list(Config) ->
- Pid = ?config(ftp, Config),
- do_append_bin(Pid, Config).
-
-
-%%-------------------------------------------------------------------------
-
-passive_send_chunk(doc) ->
- ["Open a connection to a host; cd to the directory \"incoming\"; "
- "send chunks; remove file; close the connection."];
-passive_send_chunk(suite) ->
- [];
-passive_send_chunk(Config) when is_list(Config) ->
- Pid = ?config(ftp, Config),
- do_send_chunk(Pid, Config).
-
-
-%%-------------------------------------------------------------------------
-
-passive_append_chunk(doc) ->
- ["Open a connection to a host; cd to the directory \"incoming\"; "
- "append chunks;control content remove file; close the connection."];
-passive_append_chunk(suite) ->
- [];
-passive_append_chunk(Config) when is_list(Config) ->
- Pid = ?config(ftp, Config),
- do_append_chunk(Pid, Config).
-
-
-%%-------------------------------------------------------------------------
-
-passive_recv(doc) ->
- ["Create a local file and transfer it to the remote host into the "
- "the \"incoming\" directory, remove "
- "the local file. Then open a new connection; cd to \"incoming\", "
- "lcd to the private directory; receive the file; delete the "
- "remote file; close connection; check that received file is in "
- "the correct directory; cleanup." ];
-passive_recv(suite) ->
- [];
-passive_recv(Config) when is_list(Config) ->
- Pid = ?config(ftp, Config),
- do_recv(Pid, Config).
-
-
-%%-------------------------------------------------------------------------
-
-passive_recv_bin(doc) ->
- ["Send a binary to the remote host; and retreive "
- "the file; then remove the file."];
-passive_recv_bin(suite) ->
- [];
-passive_recv_bin(Config) when is_list(Config) ->
- Pid = ?config(ftp, Config),
- do_recv_bin(Pid, Config).
-
-
-%%-------------------------------------------------------------------------
-
-passive_recv_chunk(doc) ->
- ["Send a binary to the remote host; Connect again, and retreive "
- "the file; then remove the file."];
-passive_recv_chunk(suite) ->
- [];
-passive_recv_chunk(Config) when is_list(Config) ->
- Pid = ?config(ftp, Config),
- do_recv_chunk(Pid, Config).
-
-
-%%-------------------------------------------------------------------------
-
-passive_type(doc) ->
- ["Test that we can change btween ASCCI and binary transfer mode"];
-passive_type(suite) ->
- [];
-passive_type(Config) when is_list(Config) ->
- Pid = ?config(ftp, Config),
- do_type(Pid).
-
-
-%%-------------------------------------------------------------------------
-
-passive_quote(doc) ->
- [""];
-passive_quote(suite) ->
- [];
-passive_quote(Config) when is_list(Config) ->
- Pid = ?config(ftp, Config),
- do_quote(Pid).
-
-
-%%-------------------------------------------------------------------------
-
-passive_ip_v6_disabled(doc) ->
- ["Test ipv4 command PASV"];
-passive_ip_v6_disabled(suite) ->
- [];
-passive_ip_v6_disabled(Config) when is_list(Config) ->
- Pid = ?config(ftp, Config),
- do_send(Pid, Config).
-
-
-%%-------------------------------------------------------------------------
-
-active_user(doc) ->
- ["Open an ftp connection to a host, and logon as anonymous ftp."];
-active_user(suite) ->
- [];
-active_user(Config) when is_list(Config) ->
- Pid = ?config(ftp, Config),
- do_user(Pid).
-
-
-%%-------------------------------------------------------------------------
-
-active_pwd(doc) ->
- ["Test ftp:pwd/1 & ftp:lpwd/1"];
-active_pwd(suite) ->
- [];
-active_pwd(Config) when is_list(Config) ->
- Pid = ?config(ftp, Config),
- do_pwd(Pid).
-
-
-%%-------------------------------------------------------------------------
-
-active_cd(doc) ->
- ["Open an ftp connection, log on as anonymous ftp, and cd to the"
- "directory \"/pub\" and to a non-existent directory."];
-active_cd(suite) ->
- [];
-active_cd(Config) when is_list(Config) ->
- Pid = ?config(ftp, Config),
- do_cd(Pid).
-
-
-%%-------------------------------------------------------------------------
-
-active_lcd(doc) ->
- ["Test api function ftp:lcd/2"];
-active_lcd(suite) ->
- [];
-active_lcd(Config) when is_list(Config) ->
- Pid = ?config(ftp, Config),
- PrivDir = ?config(priv_dir, Config),
- do_lcd(Pid, PrivDir).
-
-
-%%-------------------------------------------------------------------------
-
-active_ls(doc) ->
- ["Open an ftp connection; ls the current directory, and the "
- "\"incoming\" directory. We assume that ls never fails, since "
- "it's output is meant to be read by humans. "];
-active_ls(suite) ->
- [];
-active_ls(Config) when is_list(Config) ->
- Pid = ?config(ftp, Config),
- do_ls(Pid).
-
-
-%%-------------------------------------------------------------------------
-
-active_nlist(doc) ->
- ["Open an ftp connection; nlist the current directory, and the "
- "\"incoming\" directory. Nlist does not behave consistenly over "
- "operating systems. On some it is an error to have an empty "
- "directory."];
-active_nlist(suite) ->
- [];
-active_nlist(Config) when is_list(Config) ->
- Pid = ?config(ftp, Config),
- WildcardSupport = ?config(wildcard_support, Config),
- do_nlist(Pid, WildcardSupport).
-
-
-%%-------------------------------------------------------------------------
-
-active_rename(doc) ->
- ["Transfer a file to the server, and rename it; then remove it."];
-active_rename(suite) ->
- [];
-active_rename(Config) when is_list(Config) ->
- Pid = ?config(ftp, Config),
- do_rename(Pid, Config).
-
-
-%%-------------------------------------------------------------------------
-
-active_delete(doc) ->
- ["Transfer a file to the server, and then delete it"];
-active_delete(suite) ->
- [];
-active_delete(Config) when is_list(Config) ->
- Pid = ?config(ftp, Config),
- do_delete(Pid, Config).
-
-
-%%-------------------------------------------------------------------------
-
-active_mkdir(doc) ->
- ["Make a remote directory, cd to it, go to parent directory, and "
- "remove the directory."];
-active_mkdir(suite) ->
- [];
-active_mkdir(Config) when is_list(Config) ->
- Pid = ?config(ftp, Config),
- do_mkdir(Pid).
-
-
-%%-------------------------------------------------------------------------
-
-active_send(doc) ->
- ["Create a local file in priv_dir; open an ftp connection to a host; "
- "logon as anonymous ftp; cd to the directory \"incoming\"; lcd to "
- "priv_dir; send the file; get a directory listing and check that "
- "the file is on the list;, delete the remote file; get another listing "
- "and check that the file is not on the list; close the session; "
- "delete the local file."];
-active_send(suite) ->
- [];
-active_send(Config) when is_list(Config) ->
- Pid = ?config(ftp, Config),
- do_send(Pid, Config).
-
-
-%%-------------------------------------------------------------------------
-
-active_append(doc) ->
- ["Create a local file in priv_dir; open an ftp connection to a host; "
- "logon as anonymous ftp; cd to the directory \"incoming\"; lcd to "
- "priv_dir; append the file to a file at the remote side that not exits"
- "this will create the file at the remote side. Then it append the file "
- "again. When this is done it recive the remote file and control that"
- "the content is doubled in it.After that it will remove the files"];
-active_append(suite) ->
- [];
-active_append(Config) when is_list(Config) ->
- Pid = ?config(ftp, Config),
- do_append(Pid, Config).
-
-
-%%-------------------------------------------------------------------------
-
-active_send_bin(doc) ->
- ["Open a connection to a host; cd to the directory \"incoming\"; "
- "send a binary; remove file; close the connection."];
-active_send_bin(suite) ->
- [];
-active_send_bin(Config) when is_list(Config) ->
- Pid = ?config(ftp, Config),
- do_send_bin(Pid, Config).
-
-
-%%-------------------------------------------------------------------------
-
-active_append_bin(doc) ->
- ["Open a connection to a host; cd to the directory \"incoming\"; "
- "append a binary twice; get the file and compare the content"
- "remove file; close the connection."];
-active_append_bin(suite) ->
- [];
-active_append_bin(Config) when is_list(Config) ->
- Pid = ?config(ftp, Config),
- do_append_bin(Pid, Config).
-
-
-%%-------------------------------------------------------------------------
-
-active_send_chunk(doc) ->
- ["Open a connection to a host; cd to the directory \"incoming\"; "
- "send chunks; remove file; close the connection."];
-active_send_chunk(suite) ->
- [];
-active_send_chunk(Config) when is_list(Config) ->
- Pid = ?config(ftp, Config),
- do_send_chunk(Pid, Config).
-
-
-%%-------------------------------------------------------------------------
-
-active_append_chunk(doc) ->
- ["Open a connection to a host; cd to the directory \"incoming\"; "
- "append chunks;control content remove file; close the connection."];
-active_append_chunk(suite) ->
- [];
-active_append_chunk(Config) when is_list(Config) ->
- Pid = ?config(ftp, Config),
- do_append_chunk(Pid, Config).
-
-
-%%-------------------------------------------------------------------------
-
-active_recv(doc) ->
- ["Create a local file and transfer it to the remote host into the "
- "the \"incoming\" directory, remove "
- "the local file. Then open a new connection; cd to \"incoming\", "
- "lcd to the private directory; receive the file; delete the "
- "remote file; close connection; check that received file is in "
- "the correct directory; cleanup." ];
-active_recv(suite) ->
- [];
-active_recv(Config) when is_list(Config) ->
- Pid = ?config(ftp, Config),
- do_recv(Pid, Config).
-
-
-%%-------------------------------------------------------------------------
-
-active_recv_bin(doc) ->
- ["Send a binary to the remote host; and retreive "
- "the file; then remove the file."];
-active_recv_bin(suite) ->
- [];
-active_recv_bin(Config) when is_list(Config) ->
- Pid = ?config(ftp, Config),
- do_recv_bin(Pid, Config).
-
-
-%%-------------------------------------------------------------------------
-
-active_recv_chunk(doc) ->
- ["Send a binary to the remote host; Connect again, and retreive "
- "the file; then remove the file."];
-active_recv_chunk(suite) ->
- [];
-active_recv_chunk(Config) when is_list(Config) ->
- Pid = ?config(ftp, Config),
- do_recv_chunk(Pid, Config).
-
-
-%%-------------------------------------------------------------------------
-
-active_type(doc) ->
- ["Test that we can change btween ASCCI and binary transfer mode"];
-active_type(suite) ->
- [];
-active_type(Config) when is_list(Config) ->
- Pid = ?config(ftp, Config),
- do_type(Pid).
-
-
-%%-------------------------------------------------------------------------
-
-active_quote(doc) ->
- [""];
-active_quote(suite) ->
- [];
-active_quote(Config) when is_list(Config) ->
- Pid = ?config(ftp, Config),
- do_quote(Pid).
-
-
-%%-------------------------------------------------------------------------
-
-active_ip_v6_disabled(doc) ->
- ["Test ipv4 command PORT"];
-active_ip_v6_disabled(suite) ->
- [];
-active_ip_v6_disabled(Config) when is_list(Config) ->
- Pid = ?config(ftp, Config),
- do_send(Pid, Config).
-
-
-%%-------------------------------------------------------------------------
-
-api_missuse(doc)->
- ["Test that behaviour of the ftp process if the api is abused"];
-api_missuse(suite) -> [];
-api_missuse(Config) when is_list(Config) ->
- p("api_missuse -> entry"),
- Flag = process_flag(trap_exit, true),
- Pid = ?config(ftp, Config),
- Host = ftp_host(Config),
-
- %% Serious programming fault, connetion will be shut down
- p("api_missuse -> verify bad call termination (~p)", [Pid]),
- case (catch gen_server:call(Pid, {self(), foobar, 10}, infinity)) of
- {error, {connection_terminated, 'API_violation'}} ->
- ok;
- Unexpected1 ->
- exit({unexpected_result, Unexpected1})
- end,
- test_server:sleep(500),
- undefined = process_info(Pid, status),
-
- p("api_missuse -> start new client"),
- {ok, Pid2} = ?ftp_open(Host, []),
- %% Serious programming fault, connetion will be shut down
- p("api_missuse -> verify bad cast termination"),
- gen_server:cast(Pid2, {self(), foobar, 10}),
- test_server:sleep(500),
- undefined = process_info(Pid2, status),
-
- p("api_missuse -> start new client"),
- {ok, Pid3} = ?ftp_open(Host, []),
- %% Could be an innocent misstake the connection lives.
- p("api_missuse -> verify bad bang"),
- Pid3 ! foobar,
- test_server:sleep(500),
- {status, _} = process_info(Pid3, status),
- process_flag(trap_exit, Flag),
- p("api_missuse -> done"),
- ok.
-
-
-%%-------------------------------------------------------------------------
-
-not_owner(doc) ->
- ["Test what happens if a process that not owns the connection tries "
- "to use it"];
-not_owner(suite) ->
- [];
-not_owner(Config) when is_list(Config) ->
- Pid = ?config(ftp, Config),
- OtherPid = spawn_link(?MODULE, not_owner, [Pid, self()]),
-
- receive
- {OtherPid, ok} ->
- {ok, _} = ftp:pwd(Pid)
- end,
- ok.
-
-not_owner(FtpPid, Pid) ->
- {error, not_connection_owner} = ftp:pwd(FtpPid),
- ftp:close(FtpPid),
- test_server:sleep(100),
- Pid ! {self(), ok}.
-
-
-%%-------------------------------------------------------------------------
-
-
-progress_report(doc) ->
- ["Solaris 8 sparc test the option progress."];
-progress_report(suite) ->
- [progress_report_send, progress_report_recv].
-
-
-%% --
-
-progress_report_send(doc) ->
- ["Test the option progress for ftp:send/[2,3]"];
-progress_report_send(suite) ->
- [];
-progress_report_send(Config) when is_list(Config) ->
- Pid = ?config(ftp, Config),
- ReportPid =
- spawn_link(?MODULE, progress_report_receiver_init, [self(), 1]),
- do_send(Pid, Config),
- receive
- {ReportPid, ok} ->
- ok
- end.
-
-
-%% --
-
-progress_report_recv(doc) ->
- ["Test the option progress for ftp:recv/[2,3]"];
-progress_report_recv(suite) ->
- [];
-progress_report_recv(Config) when is_list(Config) ->
- Pid = ?config(ftp, Config),
- ReportPid =
- spawn_link(?MODULE, progress_report_receiver_init, [self(), 3]),
- do_recv(Pid, Config),
- receive
- {ReportPid, ok} ->
- ok
- end,
- ok.
-
-progress(#progress{} = Progress , _File, {file_size, Total}) ->
- progress_report_receiver ! start,
- Progress#progress{total = Total};
-progress(#progress{total = Total, current = Current}
- = Progress, _File, {transfer_size, 0}) ->
- progress_report_receiver ! finish,
- case Total of
- unknown ->
- ok;
- Current ->
- ok;
- _ ->
- test_server:fail({error, {progress, {total, Total},
- {current, Current}}})
- end,
- Progress;
-progress(#progress{current = Current} = Progress, _File,
- {transfer_size, Size}) ->
- progress_report_receiver ! update,
- Progress#progress{current = Current + Size}.
-
-progress_report_receiver_init(Pid, N) ->
- register(progress_report_receiver, self()),
- receive
- start ->
- ok
- end,
- progress_report_receiver_loop(Pid, N-1).
-
-progress_report_receiver_loop(Pid, N) ->
- receive
- update ->
- progress_report_receiver_loop(Pid, N);
- finish when N =:= 0 ->
- Pid ! {self(), ok};
- finish ->
- Pid ! {self(), ok},
- receive
- start ->
- ok
- end,
- progress_report_receiver_loop(Pid, N-1)
- end.
-
-
-%%-------------------------------------------------------------------------
-%% Ticket test cases
-%%-------------------------------------------------------------------------
-
-ticket_6035(doc) -> ["Test that owning process that exits with reason "
- "'shutdown' does not cause an error message."];
-ticket_6035(suite) -> [];
-ticket_6035(Config) ->
- p("ticket_6035 -> entry with"
- "~n Config: ~p", [Config]),
- PrivDir = ?config(priv_dir, Config),
- LogFile = filename:join([PrivDir,"ticket_6035.log"]),
- try
- begin
- p("ticket_6035 -> select ftpd host"),
- Host = dirty_select_ftpd_host(Config),
- p("ticket_6035 -> ftpd host selected (~p) => now spawn ftp owner", [Host]),
- Pid = spawn(?MODULE, open_wait_6035, [Host, self()]),
- p("ticket_6035 -> waiter spawned: ~p => now open error logfile (~p)",
- [Pid, LogFile]),
- error_logger:logfile({open, LogFile}),
- p("ticket_6035 -> error logfile open => now kill waiter process"),
- true = kill_ftp_proc_6035(Pid, LogFile),
- p("ticket_6035 -> waiter process killed => now close error logfile"),
- error_logger:logfile(close),
- p("ticket_6035 -> done", []),
- ok
- end
- catch
- throw:{error, not_found} ->
- {skip, "No available FTP servers"}
- end.
-
-kill_ftp_proc_6035(Pid, LogFile) ->
- p("kill_ftp_proc_6035 -> entry"),
- receive
- open ->
- p("kill_ftp_proc_6035 -> received open => now issue shutdown"),
- exit(Pid, shutdown),
- kill_ftp_proc_6035(Pid, LogFile);
- {open_failed, Reason} ->
- p("kill_ftp_proc_6035 -> received open_failed"
- "~n Reason: ~p", [Reason]),
- exit({skip, {failed_openening_server_connection, Reason}})
- after
- 5000 ->
- p("kill_ftp_proc_6035 -> timeout"),
- is_error_report_6035(LogFile)
- end.
-
-open_wait_6035({Tag, FtpServer}, From) ->
- p("open_wait_6035 -> try connect to [~p] ~s for ~p", [Tag, FtpServer, From]),
- case ftp:open(FtpServer, [{timeout, timer:seconds(15)}]) of
- {ok, Pid} ->
- p("open_wait_6035 -> connected (~p), now login", [Pid]),
- LoginResult = ftp:user(Pid,"anonymous","kldjf"),
- p("open_wait_6035 -> login result: ~p", [LoginResult]),
- From ! open,
- receive
- dummy ->
- p("open_wait_6035 -> received dummy"),
- ok
- after
- 10000 ->
- p("open_wait_6035 -> timeout"),
- ok
- end,
- p("open_wait_6035 -> done(ok)"),
- ok;
- {error, Reason} ->
- p("open_wait_6035 -> open failed"
- "~n Reason: ~p", [Reason]),
- From ! {open_failed, {Reason, FtpServer}},
- p("open_wait_6035 -> done(error)"),
- ok
- end.
-
-is_error_report_6035(LogFile) ->
- p("is_error_report_6035 -> entry"),
- Res =
- case file:read_file(LogFile) of
- {ok, Bin} ->
- Txt = binary_to_list(Bin),
- p("is_error_report_6035 -> logfile read: ~n~p", [Txt]),
- read_log_6035(Txt);
- _ ->
- false
- end,
- p("is_error_report_6035 -> logfile read result: "
- "~n ~p", [Res]),
- %% file:delete(LogFile),
- Res.
-
-read_log_6035("=ERROR REPORT===="++_Rest) ->
- p("read_log_6035 -> ERROR REPORT detected"),
- true;
-read_log_6035([H|T]) ->
- p("read_log_6035 -> OTHER: "
- "~p", [H]),
- read_log_6035(T);
-read_log_6035([]) ->
- p("read_log_6035 -> done"),
- false.
-
-
-%%--------------------------------------------------------------------
-%% Internal functions
-%%--------------------------------------------------------------------
-do_user(Pid) ->
- {error, euser} = ftp:user(Pid, ?BAD_USER, ?FTP_PASS),
- ok = ftp:user(Pid, ?FTP_USER, ?FTP_PASS),
- ok.
-
-do_pwd(Pid) ->
- {ok, "/"} = ftp:pwd(Pid),
- {ok, Path} = ftp:lpwd(Pid),
- {ok, Path} = file:get_cwd(),
- ok.
-
-do_cd(Pid) ->
- ok = ftp:cd(Pid, "/pub"),
- {error, epath} = ftp:cd(Pid, ?BAD_DIR),
- ok.
-
-do_lcd(Pid, Dir) ->
- ok = ftp:lcd(Pid, Dir),
- {error, epath} = ftp:lcd(Pid, ?BAD_DIR),
- ok.
-
-
-do_ls(Pid) ->
- {ok, _} = ftp:ls(Pid),
- {ok, _} = ftp:ls(Pid, "incoming"),
- %% neither nlist nor ls operates on a directory
- %% they operate on a pathname, which *can* be a
- %% directory, but can also be a filename or a group
- %% of files (including wildcards).
- {ok, _} = ftp:ls(Pid, "incom*"),
- ok.
-
-do_nlist(Pid, WildcardSupport) ->
- {ok, _} = ftp:nlist(Pid),
- {ok, _} = ftp:nlist(Pid, "incoming"),
- %% neither nlist nor ls operates on a directory
- %% they operate on a pathname, which *can* be a
- %% directory, but can also be a filename or a group
- %% of files (including wildcards).
- case WildcardSupport of
- true ->
- {ok, _} = ftp:nlist(Pid, "incom*"),
- ok;
- _ ->
- ok
- end.
-
-do_rename(Pid, Config) ->
- PrivDir = ?config(priv_dir, Config),
- LFile = ?config(file, Config),
- NewLFile = ?config(new_file, Config),
- AbsLFile = filename:absname(LFile, PrivDir),
- Contents = "ftp_SUITE test ...",
- ok = file:write_file(AbsLFile, list_to_binary(Contents)),
- ok = ftp:cd(Pid, "incoming"),
- ok = ftp:lcd(Pid, PrivDir),
- ftp:delete(Pid, LFile), % reset
- ftp:delete(Pid, NewLFile), % reset
- ok = ftp:send(Pid, LFile),
- {error, epath} = ftp:rename(Pid, NewLFile, LFile),
- ok = ftp:rename(Pid, LFile, NewLFile),
- ftp:delete(Pid, LFile), % cleanup
- ftp:delete(Pid, NewLFile), % cleanup
- ok.
-
-do_delete(Pid, Config) ->
- PrivDir = ?config(priv_dir, Config),
- LFile = ?config(file, Config),
- AbsLFile = filename:absname(LFile, PrivDir),
- Contents = "ftp_SUITE test ...",
- ok = file:write_file(AbsLFile, list_to_binary(Contents)),
- ok = ftp:cd(Pid, "incoming"),
- ok = ftp:lcd(Pid, PrivDir),
- ftp:delete(Pid,LFile), % reset
- ok = ftp:send(Pid, LFile),
- ok = ftp:delete(Pid,LFile),
- ok.
-
-do_mkdir(Pid) ->
- {A, B, C} = erlang:now(),
- NewDir = "nisse_" ++ integer_to_list(A) ++ "_" ++
- integer_to_list(B) ++ "_" ++ integer_to_list(C),
- ok = ftp:cd(Pid, "incoming"),
- {ok, CurrDir} = ftp:pwd(Pid),
- ok = ftp:mkdir(Pid, NewDir),
- ok = ftp:cd(Pid, NewDir),
- ok = ftp:cd(Pid, CurrDir),
- ok = ftp:rmdir(Pid, NewDir),
- ok.
-
-do_send(Pid, Config) ->
- PrivDir = ?config(priv_dir, Config),
- LFile = ?config(file, Config),
- RFile = LFile ++ ".remote",
- AbsLFile = filename:absname(LFile, PrivDir),
- Contents = "ftp_SUITE test ...",
- ok = file:write_file(AbsLFile, list_to_binary(Contents)),
- ok = ftp:cd(Pid, "incoming"),
- ok = ftp:lcd(Pid, PrivDir),
- ok = ftp:send(Pid, LFile, RFile),
- {ok, RFilesString} = ftp:nlist(Pid),
- RFiles = split(RFilesString),
- true = lists:member(RFile, RFiles),
- ok = ftp:delete(Pid, RFile),
- case ftp:nlist(Pid) of
- {error, epath} ->
- ok; % No files
- {ok, RFilesString1} ->
- RFiles1 = split(RFilesString1),
- false = lists:member(RFile, RFiles1)
- end,
- ok = file:delete(AbsLFile).
-
-do_append(Pid, Config) ->
- PrivDir = ?config(priv_dir, Config),
- LFile = ?config(file, Config),
- RFile = ?config(new_file, Config),
- AbsLFile = filename:absname(LFile, PrivDir),
- Contents = "ftp_SUITE test:appending\r\n",
-
- ok = file:write_file(AbsLFile, list_to_binary(Contents)),
- ok = ftp:cd(Pid, "incoming"),
- ok = ftp:lcd(Pid, PrivDir),
-
- %% remove files from earlier failed test case
- ftp:delete(Pid, RFile),
- ftp:delete(Pid, LFile),
-
- ok = ftp:append(Pid, LFile, RFile),
- ok = ftp:append(Pid, LFile, RFile),
- ok = ftp:append(Pid, LFile),
-
- %% Control the contents of the file
- {ok, Bin1} = ftp:recv_bin(Pid, RFile),
- ok = ftp:delete(Pid, RFile),
- ok = file:delete(AbsLFile),
- ok = check_content(binary_to_list(Bin1), Contents, double),
-
- {ok, Bin2} = ftp:recv_bin(Pid, LFile),
- ok = ftp:delete(Pid, LFile),
- ok = check_content(binary_to_list(Bin2), Contents, singel),
- ok.
-
-do_send_bin(Pid, Config) ->
- File = ?config(file, Config),
- Contents = "ftp_SUITE test ...",
- Bin = list_to_binary(Contents),
- ok = ftp:cd(Pid, "incoming"),
- {error, enotbinary} = ftp:send_bin(Pid, Contents, File),
- ok = ftp:send_bin(Pid, Bin, File),
- {ok, RFilesString} = ftp:nlist(Pid),
- RFiles = split(RFilesString),
- true = lists:member(File, RFiles),
- ok = ftp:delete(Pid, File),
- ok.
-
-do_append_bin(Pid, Config) ->
- File = ?config(file, Config),
- Contents = "ftp_SUITE test ...",
- Bin = list_to_binary(Contents),
- ok = ftp:cd(Pid, "incoming"),
- {error, enotbinary} = ftp:append_bin(Pid, Contents, File),
- ok = ftp:append_bin(Pid, Bin, File),
- ok = ftp:append_bin(Pid, Bin, File),
- %% Control the contents of the file
- {ok, Bin2} = ftp:recv_bin(Pid, File),
- ok = ftp:delete(Pid,File),
- ok = check_content(binary_to_list(Bin2),binary_to_list(Bin), double).
-
-do_send_chunk(Pid, Config) ->
- File = ?config(file, Config),
- Contents = "ftp_SUITE test ...",
- Bin = list_to_binary(Contents),
- ok = ftp:cd(Pid, "incoming"),
- ok = ftp:send_chunk_start(Pid, File),
- {error, echunk} = ftp:cd(Pid, "incoming"),
- {error, enotbinary} = ftp:send_chunk(Pid, Contents),
- ok = ftp:send_chunk(Pid, Bin),
- ok = ftp:send_chunk(Pid, Bin),
- ok = ftp:send_chunk_end(Pid),
- {ok, RFilesString} = ftp:nlist(Pid),
- RFiles = split(RFilesString),
- true = lists:member(File, RFiles),
- ok = ftp:delete(Pid, File),
- ok.
-
-do_append_chunk(Pid, Config) ->
- File = ?config(file, Config),
- Contents = ["ER","LE","RL"],
- ok = ftp:cd(Pid, "incoming"),
- ok = ftp:append_chunk_start(Pid, File),
- {error, enotbinary} = ftp:append_chunk(Pid, lists:nth(1,Contents)),
- ok = ftp:append_chunk(Pid,list_to_binary(lists:nth(1,Contents))),
- ok = ftp:append_chunk(Pid,list_to_binary(lists:nth(2,Contents))),
- ok = ftp:append_chunk(Pid,list_to_binary(lists:nth(3,Contents))),
- ok = ftp:append_chunk_end(Pid),
- %%Control the contents of the file
- {ok, Bin2} = ftp:recv_bin(Pid, File),
- ok = check_content(binary_to_list(Bin2),"ERL", double),
- ok = ftp:delete(Pid, File),
- ok.
-
-do_recv(Pid, Config) ->
- PrivDir = ?config(priv_dir, Config),
- File = ?config(file, Config),
- Newfile = ?config(new_file, Config),
- AbsFile = filename:absname(File, PrivDir),
- Contents = "ftp_SUITE:recv test ...",
- ok = file:write_file(AbsFile, list_to_binary(Contents)),
- ok = ftp:cd(Pid, "incoming"),
- ftp:delete(Pid, File), % reset
- ftp:lcd(Pid, PrivDir),
- ok = ftp:send(Pid, File),
- ok = file:delete(AbsFile), % cleanup
- test_server:sleep(100),
- ok = ftp:lcd(Pid, PrivDir),
- ok = ftp:recv(Pid, File),
- {ok, Files} = file:list_dir(PrivDir),
- true = lists:member(File, Files),
- ok = file:delete(AbsFile), % cleanup
- ok = ftp:recv(Pid, File, Newfile),
- ok = ftp:delete(Pid, File), % cleanup
- ok.
-
-do_recv_bin(Pid, Config) ->
- File = ?config(file, Config),
- Contents1 = "ftp_SUITE test ...",
- Bin1 = list_to_binary(Contents1),
- ok = ftp:cd(Pid, "incoming"),
- ok = ftp:send_bin(Pid, Bin1, File),
- test_server:sleep(100),
- {ok, Bin2} = ftp:recv_bin(Pid, File),
- ok = ftp:delete(Pid, File), % cleanup
- Contents2 = binary_to_list(Bin2),
- Contents1 = Contents2,
- ok.
-
-do_recv_chunk(Pid, Config) ->
- File = ?config(file, Config),
- Data = "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
- "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB"
- "CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC"
- "DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD"
- "EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE"
- "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
- "GGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGG"
- "HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH"
- "IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII",
-
- Contents1 = lists:flatten(lists:duplicate(10, Data)),
- Bin1 = list_to_binary(Contents1),
- ok = ftp:cd(Pid, "incoming"),
- ok = ftp:type(Pid, binary),
- ok = ftp:send_bin(Pid, Bin1, File),
- test_server:sleep(100),
- {error, "ftp:recv_chunk_start/2 not called"} = recv_chunk(Pid, <<>>),
- ok = ftp:recv_chunk_start(Pid, File),
- {ok, Contents2} = recv_chunk(Pid, <<>>),
- ok = ftp:delete(Pid, File), % cleanup
- ok = find_diff(Contents2, Contents1, 1),
- ok.
-
-do_type(Pid) ->
- ok = ftp:type(Pid, ascii),
- ok = ftp:type(Pid, binary),
- ok = ftp:type(Pid, ascii),
- {error, etype} = ftp:type(Pid, foobar),
- ok.
-
-do_quote(Pid) ->
- ["257 \"/\""++_Rest] = ftp:quote(Pid, "pwd"), %% 257
- [_| _] = ftp:quote(Pid, "help"),
- %% This negativ test causes some ftp servers to hang. This test
- %% is not important for the client, so we skip it for now.
- %%["425 Can't build data connection: Connection refused."]
- %% = ftp:quote(Pid, "list"),
- ok.
-
- watch_dog(Config) ->
- Dog = test_server:timetrap(inets_test_lib:minutes(1)),
- NewConfig = lists:keydelete(watchdog, 1, Config),
- [{watchdog, Dog} | NewConfig].
-
- close_connection(Config) ->
- case ?config(ftp, Config) of
- Pid when is_pid(Pid) ->
- ok = ftp:close(Pid),
- lists:delete({ftp, Pid}, Config);
- _ ->
- Config
- end.
-
-ftp_host(Config) ->
- case ?config(ftp_remote_host, Config) of
- undefined ->
- exit({skip, "No host specified"});
- Host ->
- Host
- end.
-
-check_content(RContent, LContent, Amount) ->
- LContent2 = case Amount of
- double ->
- LContent ++ LContent;
- singel ->
- LContent
- end,
- case string:equal(RContent, LContent2) of
- true ->
- ok;
- false ->
- %% Find where the diff is
- Where = find_diff(RContent, LContent2, 1),
- Where
- end.
-
-find_diff(A, A, _) ->
- ok;
-find_diff([H|T1], [H|T2], Pos) ->
- find_diff(T1, T2, Pos+1);
-find_diff(RC, LC, Pos) ->
- {error, {diff, Pos, RC, LC}}.
-
-recv_chunk(Pid, Acc) ->
- case ftp:recv_chunk(Pid) of
- ok ->
- {ok, binary_to_list(Acc)};
- {ok, Bin} ->
- recv_chunk(Pid, <<Acc/binary, Bin/binary>>);
- Error ->
- Error
- end.
-
-split(Cs) ->
- split(Cs, [], []).
-
-split([$\r, $\n| Cs], I, Is) ->
- split(Cs, [], [lists:reverse(I)| Is]);
-split([C| Cs], I, Is) ->
- split(Cs, [C| I], Is);
-split([], I, Is) ->
- lists:reverse([lists:reverse(I)| Is]).
-
-do_ftp_open(Host, Opts) ->
- p("do_ftp_open -> entry with"
- "~n Host: ~p"
- "~n Opts: ~p", [Host, Opts]),
- case ftp:open(Host, Opts) of
- {ok, _} = OK ->
- OK;
- {error, Reason} ->
- Str =
- lists:flatten(
- io_lib:format("Unable to reach test FTP server ~p (~p)",
- [Host, Reason])),
- throw({skip, Str})
- end.
-
-
-passwd() ->
- Host =
- case inet:gethostname() of
- {ok, H} ->
- H;
- _ ->
- "localhost"
- end,
- "ftp_SUITE@" ++ Host.
-
-ftpd_hosts(Config) ->
- DataDir = ?config(data_dir, Config),
- FileName = filename:join([DataDir, "../ftp_SUITE_data/", ftpd_hosts]),
- p("FileName: ~p", [FileName]),
- case file:consult(FileName) of
- {ok, [Hosts]} when is_list(Hosts) ->
- Hosts;
- _ ->
- []
- end.
-
-wrapper(Prefix,doc,Func) ->
- Prefix++Func(doc);
-wrapper(_,X,Func) ->
- Func(X).
-
-data_dir(Config) ->
- case ?config(data_dir, Config) of
- List when (length(List) > 0) ->
- PathList = filename:split(List),
- {NewPathList,_} = lists:split((length(PathList)-1), PathList),
- DataDir = filename:join(NewPathList ++ [ftp_SUITE_data]),
- NewConfig =
- lists:keyreplace(data_dir,1,Config, {data_dir,DataDir}),
- NewConfig;
- _ -> Config
- end.
-
-
-
-p(F) ->
- p(F, []).
-
-p(F, A) ->
- case get(ftp_testcase) of
- undefined ->
- io:format("~w [~w] " ++ F ++ "~n", [?MODULE, self() | A]);
- TC when is_atom(TC) ->
- io:format("~w [~w] ~w:" ++ F ++ "~n", [?MODULE, self(), TC | A])
- end.
diff --git a/lib/inets/test/ftp_ticket_test.erl b/lib/inets/test/ftp_ticket_test.erl
deleted file mode 100644
index fe4ab35728..0000000000
--- a/lib/inets/test/ftp_ticket_test.erl
+++ /dev/null
@@ -1,61 +0,0 @@
-%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2006-2010. 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(ftp_ticket_test).
-
--compile(export_all).
-
--define(LIB_MOD,ftp_suite_lib).
--define(CASE_WRAPPER(_A_,_B_,_C_),?LIB_MOD:wrapper(_A_,_B_,_C_)).
--define(PLATFORM,"Solaris 8 sparc ").
-
-
-%% Test server callbacks
-init_per_testcase(Case, Config) ->
- ftp_suite_lib:init_per_testcase(Case, Config).
-
-end_per_testcase(Case, Config) ->
- ftp_suite_lib:end_per_testcase(Case, Config).
-
-
-all() ->
- tickets().
-
-groups() ->
- [].
-
-init_per_group(_GroupName, Config) ->
- Config.
-
-end_per_group(_GroupName, Config) ->
- Config.
-
-
-init_per_suite(Config) ->
- ?LIB_MOD:ftpd_init(ticket_test, Config).
-
-tickets() ->
- [ticket_6035].
-
-
-end_per_suite(Config) ->
- ?LIB_MOD:ftpd_fin(Config).
-
-ticket_6035(X) -> ?LIB_MOD:ticket_6035(X).
diff --git a/lib/inets/test/ftp_windows_2003_server_test.erl b/lib/inets/test/ftp_windows_2003_server_test.erl
deleted file mode 100644
index 32f25713f8..0000000000
--- a/lib/inets/test/ftp_windows_2003_server_test.erl
+++ /dev/null
@@ -1,167 +0,0 @@
-%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2005-2011. 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(ftp_windows_2003_server_test).
-
--compile(export_all).
-
--include_lib("common_test/include/ct.hrl").
-
--define(LIB_MOD,ftp_suite_lib).
--define(CASE_WRAPPER(_A_,_B_,_C_),?LIB_MOD:wrapper(_A_,_B_,_C_)).
--define(PLATFORM,"Windows 2003 server ").
-
-%% Test server callback functions
-%%--------------------------------------------------------------------
-%% 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) ->
- {File, NewFile} = ?LIB_MOD:test_filenames(),
- NewConfig = [{file, File}, {new_file, NewFile} | Config],
- ?LIB_MOD:ftpd_init(windows_2003_server, NewConfig).
-
-%%--------------------------------------------------------------------
-%% 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) ->
- ?LIB_MOD:ftpd_fin(Config).
-
-%%--------------------------------------------------------------------
-%% Function: init_per_testcase(TestCase, 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.
-%% Description: Initiation before each test case
-%%--------------------------------------------------------------------
-init_per_testcase(Case, Config) ->
- ftp_suite_lib:init_per_testcase(Case, Config).
-%%--------------------------------------------------------------------
-%% Function: end_per_testcase(TestCase, 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) ->
- ftp_suite_lib:end_per_testcase(Case, Config).
-
-%%--------------------------------------------------------------------
-%% Function: all(Clause) -> TestCases
-%% Clause - atom() - suite | doc
-%% TestCases - [Case]
-%% Case - atom()
-%% Name of a test case.
-%% Description: Returns a list of all test cases in this test suite
-%%--------------------------------------------------------------------
-all() ->
- [
- open,
- open_port,
- {group, passive},
- {group, active},
- api_missuse,
- not_owner,
- {group, progress_report}
- ].
-
-groups() ->
- [
- {passive, [], ftp_suite_lib:passive(suite)},
- {active, [], ftp_suite_lib:active(suite)},
- {progress_report, [], ftp_suite_lib:progress_report(suite)}
- ].
-
-init_per_group(_GroupName, Config) ->
- Config.
-
-end_per_group(_GroupName, Config) ->
- Config.
-
-
-%% Test cases starts here.
-
-open(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:open/1).
-open_port(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:open_port/1).
-api_missuse(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:api_missuse/1).
-not_owner(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:not_owner/1).
-
-passive_user(X) -> ?LIB_MOD:passive_user(X).
-passive_pwd(X) -> ?LIB_MOD:passive_pwd(X).
-passive_cd(X) -> ?LIB_MOD:passive_cd(X).
-passive_lcd(X) -> ?LIB_MOD:passive_lcd(X).
-passive_ls(X) -> ?LIB_MOD:passive_ls(X).
-passive_nlist(X) -> ?LIB_MOD:passive_nlist(X).
-passive_rename(X) -> ?LIB_MOD:passive_rename(X).
-passive_delete(X) -> ?LIB_MOD:passive_delete(X).
-passive_mkdir(X) -> ?LIB_MOD:passive_mkdir(X).
-passive_send(X) -> ?LIB_MOD:passive_send(X).
-passive_send_bin(X) -> ?LIB_MOD:passive_send_bin(X).
-passive_send_chunk(X) -> ?LIB_MOD:passive_send_chunk(X).
-passive_append(X) -> ?LIB_MOD:passive_append(X).
-passive_append_bin(X) -> ?LIB_MOD:passive_append_bin(X).
-passive_append_chunk(X) -> ?LIB_MOD:passive_append_chunk(X).
-passive_recv(X) -> ?LIB_MOD:passive_recv(X).
-passive_recv_bin(X) -> ?LIB_MOD:passive_recv_bin(X).
-passive_recv_chunk(X) -> ?LIB_MOD:passive_recv_chunk(X).
-passive_type(X) -> ?LIB_MOD:passive_type(X).
-passive_quote(X) -> ?LIB_MOD:passive_quote(X).
-passive_ip_v6_disabled(X) -> ?LIB_MOD:passive_ip_v6_disabled(X).
-active_user(X) -> ?LIB_MOD:active_user(X).
-active_pwd(X) -> ?LIB_MOD:active_pwd(X).
-active_cd(X) -> ?LIB_MOD:active_cd(X).
-active_lcd(X) -> ?LIB_MOD:active_lcd(X).
-active_ls(X) -> ?LIB_MOD:active_ls(X).
-active_nlist(X) -> ?LIB_MOD:active_nlist(X).
-active_rename(X) -> ?LIB_MOD:active_rename(X).
-active_delete(X) -> ?LIB_MOD:active_delete(X).
-active_mkdir(X) -> ?LIB_MOD:active_mkdir(X).
-active_send(X) -> ?LIB_MOD:active_send(X).
-active_send_bin(X) -> ?LIB_MOD:active_send_bin(X).
-active_send_chunk(X) -> ?LIB_MOD:active_send_chunk(X).
-active_append(X) -> ?LIB_MOD:active_append(X).
-active_append_bin(X) -> ?LIB_MOD:active_append_bin(X).
-active_append_chunk(X) -> ?LIB_MOD:active_append_chunk(X).
-active_recv(X) -> ?LIB_MOD:active_recv(X).
-active_recv_bin(X) -> ?LIB_MOD:active_recv_bin(X).
-active_recv_chunk(X) -> ?LIB_MOD:active_recv_chunk(X).
-active_type(X) -> ?LIB_MOD:active_type(X).
-active_quote(X) -> ?LIB_MOD:active_quote(X).
-active_ip_v6_disabled(X) -> ?LIB_MOD:active_ip_v6_disabled(X).
-progress_report_send(X) -> ?LIB_MOD:progress_report_send(X).
-progress_report_recv(X) -> ?LIB_MOD:progress_report_recv(X).
-
-fin(Config) ->
- ?LIB_MOD:ftpd_fin(Config).
diff --git a/lib/inets/test/ftp_windows_xp_test.erl b/lib/inets/test/ftp_windows_xp_test.erl
deleted file mode 100644
index 06d919ba00..0000000000
--- a/lib/inets/test/ftp_windows_xp_test.erl
+++ /dev/null
@@ -1,157 +0,0 @@
-%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2005-2010. 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(ftp_windows_xp_test).
-
--compile(export_all).
-
--include_lib("common_test/include/ct.hrl").
-
--define(LIB_MOD,ftp_suite_lib).
--define(CASE_WRAPPER(_A_,_B_,_C_),?LIB_MOD:wrapper(_A_,_B_,_C_)).
--define(PLATFORM,"Windows xp ").
-
-%% Test server callback functions
-%%--------------------------------------------------------------------
-%% 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) ->
- {File, NewFile} = ?LIB_MOD:test_filenames(),
- NewConfig = [{file, File}, {new_file, NewFile} | Config],
- ?LIB_MOD:ftpd_init(windows_xp, NewConfig).
-
-%%--------------------------------------------------------------------
-%% 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) ->
- ?LIB_MOD:ftpd_fin(Config).
-
-%%--------------------------------------------------------------------
-%% Function: init_per_testcase(TestCase, 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.
-%% Description: Initiation before each test case
-%%--------------------------------------------------------------------
-init_per_testcase(Case, Config) ->
- ftp_suite_lib:init_per_testcase(Case, Config).
-%%--------------------------------------------------------------------
-%% Function: end_per_testcase(TestCase, 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) ->
- ftp_suite_lib:end_per_testcase(Case, Config).
-
-%%--------------------------------------------------------------------
-%% Function: all(Clause) -> TestCases
-%% Clause - atom() - suite | doc
-%% TestCases - [Case]
-%% Case - atom()
-%% Name of a test case.
-%% Description: Returns a list of all test cases in this test suite
-%%--------------------------------------------------------------------
-all() ->
- [open, open_port, {group, passive}, {group, active},
- api_missuse, not_owner, {group, progress_report}].
-
-groups() ->
- [{passive, [], ftp_suite_lib:passive(suite)},
- {active, [], ftp_suite_lib:active(suite)},
- {progress_report, [],
- ftp_suite_lib:progress_report(suite)}].
-
-init_per_group(_GroupName, Config) ->
- Config.
-
-end_per_group(_GroupName, Config) ->
- Config.
-
-
-open(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:open/1).
-open_port(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:open_port/1).
-api_missuse(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:api_missuse/1).
-not_owner(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:not_owner/1).
-
-passive_user(X) -> ?LIB_MOD:passive_user(X).
-passive_pwd(X) -> ?LIB_MOD:passive_pwd(X).
-passive_cd(X) -> ?LIB_MOD:passive_cd(X).
-passive_lcd(X) -> ?LIB_MOD:passive_lcd(X).
-passive_ls(X) -> ?LIB_MOD:passive_ls(X).
-passive_nlist(X) -> ?LIB_MOD:passive_nlist(X).
-passive_rename(X) -> ?LIB_MOD:passive_rename(X).
-passive_delete(X) -> ?LIB_MOD:passive_delete(X).
-passive_mkdir(X) -> ?LIB_MOD:passive_mkdir(X).
-passive_send(X) -> ?LIB_MOD:passive_send(X).
-passive_send_bin(X) -> ?LIB_MOD:passive_send_bin(X).
-passive_send_chunk(X) -> ?LIB_MOD:passive_send_chunk(X).
-passive_append(X) -> ?LIB_MOD:passive_append(X).
-passive_append_bin(X) -> ?LIB_MOD:passive_append_bin(X).
-passive_append_chunk(X) -> ?LIB_MOD:passive_append_chunk(X).
-passive_recv(X) -> ?LIB_MOD:passive_recv(X).
-passive_recv_bin(X) -> ?LIB_MOD:passive_recv_bin(X).
-passive_recv_chunk(X) -> ?LIB_MOD:passive_recv_chunk(X).
-passive_type(X) -> ?LIB_MOD:passive_type(X).
-passive_quote(X) -> ?LIB_MOD:passive_quote(X).
-passive_ip_v6_disabled(X) -> ?LIB_MOD:passive_ip_v6_disabled(X).
-active_user(X) -> ?LIB_MOD:active_user(X).
-active_pwd(X) -> ?LIB_MOD:active_pwd(X).
-active_cd(X) -> ?LIB_MOD:active_cd(X).
-active_lcd(X) -> ?LIB_MOD:active_lcd(X).
-active_ls(X) -> ?LIB_MOD:active_ls(X).
-active_nlist(X) -> ?LIB_MOD:active_nlist(X).
-active_rename(X) -> ?LIB_MOD:active_rename(X).
-active_delete(X) -> ?LIB_MOD:active_delete(X).
-active_mkdir(X) -> ?LIB_MOD:active_mkdir(X).
-active_send(X) -> ?LIB_MOD:active_send(X).
-active_send_bin(X) -> ?LIB_MOD:active_send_bin(X).
-active_send_chunk(X) -> ?LIB_MOD:active_send_chunk(X).
-active_append(X) -> ?LIB_MOD:active_append(X).
-active_append_bin(X) -> ?LIB_MOD:active_append_bin(X).
-active_append_chunk(X) -> ?LIB_MOD:active_append_chunk(X).
-active_recv(X) -> ?LIB_MOD:active_recv(X).
-active_recv_bin(X) -> ?LIB_MOD:active_recv_bin(X).
-active_recv_chunk(X) -> ?LIB_MOD:active_recv_chunk(X).
-active_type(X) -> ?LIB_MOD:active_type(X).
-active_quote(X) -> ?LIB_MOD:active_quote(X).
-active_ip_v6_disabled(X) -> ?LIB_MOD:active_ip_v6_disabled(X).
-progress_report_send(X) -> ?LIB_MOD:progress_report_send(X).
-progress_report_recv(X) -> ?LIB_MOD:progress_report_recv(X).
-
-fin(Config) ->
- ?LIB_MOD:ftpd_fin(Config).
diff --git a/lib/inets/test/http_format_SUITE.erl b/lib/inets/test/http_format_SUITE.erl
index c5920a3968..a2b463e98c 100644
--- a/lib/inets/test/http_format_SUITE.erl
+++ b/lib/inets/test/http_format_SUITE.erl
@@ -1,44 +1,31 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2004-2013. All Rights Reserved.
+%% Copyright Ericsson AB 2004-2015. 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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% 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.
+%% http://www.apache.org/licenses/LICENSE-2.0
+%%
+%% Unless required by applicable law or agreed to in writing, software
+%% distributed under the License is distributed on an "AS IS" BASIS,
+%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+%% See the License for the specific language governing permissions and
+%% limitations under the License.
%%
%% %CopyrightEnd%
%%
%%
-module(http_format_SUITE).
--author('[email protected]').
-include_lib("common_test/include/ct.hrl").
--include("test_server_line.hrl").
-include("http_internal.hrl").
-%% Test server specific exports
--export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1, init_per_group/2,end_per_group/2, init_per_testcase/2, end_per_testcase/2]).
-
-%% Test cases must be exported.
--export([ chunk_decode/1, chunk_encode/1,
- chunk_extensions_otp_6005/1, chunk_decode_otp_6264/1,
- chunk_decode_empty_chunk_otp_6511/1,
- chunk_decode_trailer/1,
- http_response/1, http_request/1, validate_request_line/1,
- esi_parse_headers/1, cgi_parse_headers/1,
- is_absolut_uri/1, convert_netscapecookie_date/1,
- check_content_length_encoding/1]).
-
-suite() -> [{ct_hooks,[ts_install_cth]}].
+%% Note: This directive should only be used in test suites.
+-compile(export_all).
all() ->
[{group, chunk}, http_response, http_request,
@@ -51,7 +38,8 @@ groups() ->
[chunk_decode, chunk_encode, chunk_extensions_otp_6005,
chunk_decode_otp_6264,
chunk_decode_empty_chunk_otp_6511,
- chunk_decode_trailer]}].
+ chunk_whitespace_suffix,
+ chunk_decode_trailer, chunk_max_headersize, chunk_max_bodysize, chunk_not_hex]}].
init_per_suite(Config) ->
Config.
@@ -67,25 +55,17 @@ end_per_group(_GroupName, Config) ->
init_per_testcase(_, Config) ->
- Dog = test_server:timetrap(?t:minutes(1)),
- NewConfig = lists:keydelete(watchdog, 1, Config),
- [{watchdog, Dog} | NewConfig].
+ Config.
-end_per_testcase(_, Config) ->
- Dog = ?config(watchdog, Config),
- test_server:timetrap_cancel(Dog),
+end_per_testcase(_, _) ->
ok.
%%-------------------------------------------------------------------------
%% Test cases starts here.
%%-------------------------------------------------------------------------
-
-%%-------------------------------------------------------------------------
-chunk_decode(doc) ->
- ["Test http_chunk:decode/3"];
-chunk_decode(suite) ->
- [];
+chunk_decode() ->
+ [{doc, "Test http_chunk:decode/3"}].
chunk_decode(Config) when is_list(Config) ->
ReqHeaders = #http_request_h{'transfer-encoding' = "chunked"},
ChunkedBody = "A" ++ ?CRLF ++ "1234567890" ++ ?CRLF ++ "4" ++
@@ -108,15 +88,11 @@ chunk_decode(Config) when is_list(Config) ->
?HTTP_MAX_BODY_SIZE, ?HTTP_MAX_HEADER_SIZE),
{_, Body} = parse(Module, Function, Args, tl(NewChunkedBody)),
- "1234567890HEJ!" = binary_to_list(Body),
-
- ok.
+ "1234567890HEJ!" = binary_to_list(Body).
%%-------------------------------------------------------------------------
-chunk_extensions_otp_6005(doc) ->
- ["Make sure so called extensions are ignored"];
-chunk_extensions_otp_6005(suite) ->
- [];
+chunk_extensions_otp_6005() ->
+ [{doc, "Make sure so called extensions are ignored"}].
chunk_extensions_otp_6005(Config) when is_list(Config)->
ChunkedBody = "A;ignore this" ++ ?CRLF ++ "1234567890" ++
?CRLF ++ "4" ++ ?CRLF ++ "HEJ!"++ ?CRLF ++ "0" ++
@@ -135,14 +111,11 @@ chunk_extensions_otp_6005(Config) when is_list(Config)->
?HTTP_MAX_BODY_SIZE, ?HTTP_MAX_HEADER_SIZE),
{_, NewBody} = parse(Module1, Function1, Args1, tl(ChunkedBody1)),
- "1234567890HEJ!" = binary_to_list(NewBody),
- ok.
+ "1234567890HEJ!" = binary_to_list(NewBody).
%%-------------------------------------------------------------------------
-chunk_decode_otp_6264(doc) ->
- ["Check that 0 in the body does not count as the last chunk"];
-chunk_decode_otp_6264(suite) ->
- [];
+chunk_decode_otp_6264() ->
+ [{doc, "Check that 0 in the body does not count as the last chunk"}].
chunk_decode_otp_6264(Config) when is_list(Config)->
ChunkedBody = "A;ignore this" ++ ?CRLF ++ "1234567890" ++
?CRLF ++ "4" ++ ?CRLF ++ "0123"++ ?CRLF ++ "0" ++
@@ -172,27 +145,33 @@ chunk_decode_otp_6264(Config) when is_list(Config)->
?HTTP_MAX_BODY_SIZE, ?HTTP_MAX_HEADER_SIZE),
{_, NewBody} = parse(Module1, Function1, Args1, tl(NewChunkedBody1)),
- "12345678900" = binary_to_list(NewBody),
-
- ok.
+ "12345678900" = binary_to_list(NewBody).
%%-------------------------------------------------------------------------
-chunk_decode_empty_chunk_otp_6511(doc) ->
- [""];
-chunk_decode_empty_chunk_otp_6511(suite) ->
- [];
chunk_decode_empty_chunk_otp_6511(Config) when is_list(Config) ->
ChunkedBody = "0" ++ ?CRLF ++ ?CRLF,
{ok,{["content-length:0"],<<>>}} =
http_chunk:decode(list_to_binary(ChunkedBody),
- ?HTTP_MAX_BODY_SIZE, ?HTTP_MAX_HEADER_SIZE),
- ok.
+ ?HTTP_MAX_BODY_SIZE, ?HTTP_MAX_HEADER_SIZE).
%%-------------------------------------------------------------------------
-chunk_decode_trailer(doc) ->
- ["Make sure trailers are handled correctly. Trailers should"
- "become new headers"];
-chunk_decode_trailer(suite) ->
- [];
+chunk_whitespace_suffix() ->
+ [{doc, "Test whitespace after chunked length header"}].
+chunk_whitespace_suffix(Config) when is_list(Config) ->
+ ChunkedBody = "1a ; ignore-stuff-here" ++ ?CRLF ++
+ "abcdefghijklmnopqrstuvwxyz" ++ ?CRLF ++ "10 " ++ ?CRLF
+ ++ "1234567890abcdef" ++ ?CRLF ++ "0 " ++ ?CRLF
+ ++ "some-footer:some-value" ++ ?CRLF
+ ++ "another-footer:another-value" ++ ?CRLF ++ ?CRLF,
+ {ok, {["content-length:42", "another-footer:another-value",
+ "some-footer:some-value", ""],
+ <<"abcdefghijklmnopqrstuvwxyz1234567890abcdef">>}} =
+ http_chunk:decode(list_to_binary(ChunkedBody),
+ ?HTTP_MAX_BODY_SIZE, ?HTTP_MAX_HEADER_SIZE).
+
+%%-------------------------------------------------------------------------
+chunk_decode_trailer() ->
+ [{doc,"Make sure trailers are handled correctly. Trailers should"
+ "become new headers"}].
chunk_decode_trailer(Config) when is_list(Config)->
ChunkedBody = "1a; ignore-stuff-here" ++ ?CRLF ++
"abcdefghijklmnopqrstuvwxyz" ++ ?CRLF ++ "10" ++ ?CRLF
@@ -248,30 +227,79 @@ chunk_decode_trailer(Config) when is_list(Config)->
?HTTP_MAX_BODY_SIZE, ?HTTP_MAX_HEADER_SIZE),
{_, NewBody} = parse(Module1, Function1, Args1, tl(ChunkedBody3)),
- "abcdefghijklmnopqrstuvwxyz1234567890abcdef" = binary_to_list(NewBody),
-
- ok.
+ "abcdefghijklmnopqrstuvwxyz1234567890abcdef" = binary_to_list(NewBody).
%%-------------------------------------------------------------------------
-chunk_encode(doc) ->
- ["Test http_chunk:encode/1 & http_chunk:encode_last/0"];
-chunk_encode(suite) ->
- [];
+chunk_encode() ->
+ [{doc, "Test http_chunk:encode/1 & http_chunk:encode_last/0"}].
chunk_encode(Config) when is_list(Config) ->
<<54, ?CR, ?LF, 102,111,111,98,97,114, ?CR, ?LF>> =
http_chunk:encode(list_to_binary("foobar")),
["6", ?CR, ?LF,"foobar", ?CR, ?LF] = http_chunk:encode("foobar"),
- <<$0, ?CR, ?LF, ?CR, ?LF >> = http_chunk:encode_last(),
- ok.
-
+ <<$0, ?CR, ?LF, ?CR, ?LF >> = http_chunk:encode_last().
+%%-------------------------------------------------------------------------
+chunk_max_headersize() ->
+ [{doc, "Test max header limit"}].
+chunk_max_headersize(Config) when is_list(Config) ->
+ ChunkedBody = "1a; ignore-stuff-here" ++ ?CRLF ++
+ "abcdefghijklmnopqrstuvwxyz" ++ ?CRLF ++ "10" ++ ?CRLF
+ ++ "1234567890abcdef" ++ ?CRLF ++ "0" ++ ?CRLF
+ ++ "some-footer:some-value" ++ ?CRLF
+ ++ "another-footer:another-value" ++ ?CRLF ++ ?CRLF,
+
+ {ok, {_, _}} =
+ http_chunk:decode(list_to_binary(ChunkedBody),
+ ?HTTP_MAX_BODY_SIZE, ?HTTP_MAX_HEADER_SIZE),
+
+ %% Too long in length header
+ {error,{header_too_long, {max, 1}}} =
+ (catch http_chunk:decode(list_to_binary(ChunkedBody),
+ ?HTTP_MAX_BODY_SIZE, 1)),
+
+ %% Too long in extension field
+ {error,{header_too_long, {max, 10}}} =
+ (catch http_chunk:decode(list_to_binary(ChunkedBody),
+ ?HTTP_MAX_BODY_SIZE, 10)),
+
+ %% Too long in trailer
+ {error,{header_too_long, {max, 30}}} =
+ (catch http_chunk:decode(list_to_binary(ChunkedBody),
+ ?HTTP_MAX_BODY_SIZE, 30)).
+%%-------------------------------------------------------------------------
+chunk_not_hex() ->
+ [{doc, "Test bad chunked length header"}].
+chunk_not_hex(Config) when is_list(Config) ->
+ ChunkedBody = "åäö; ignore-stuff-here" ++ ?CRLF ++
+ "abcdefghijklmnopqrstuvwxyz" ++ ?CRLF ++ "10" ++ ?CRLF
+ ++ "1234567890abcdef" ++ ?CRLF ++ "0" ++ ?CRLF
+ ++ "some-footer:some-value" ++ ?CRLF
+ ++ "another-footer:another-value" ++ ?CRLF ++ ?CRLF,
+ {error,{chunk_size, "åäö"}} =
+ (catch http_chunk:decode(list_to_binary(ChunkedBody),
+ ?HTTP_MAX_BODY_SIZE, ?HTTP_MAX_HEADER_SIZE)).
+%%-------------------------------------------------------------------------
+chunk_max_bodysize() ->
+ [{doc, "Test max body limit"}].
+chunk_max_bodysize(Config) when is_list(Config) ->
+ ChunkedBody = "1a; ignore-stuff-here" ++ ?CRLF ++
+ "abcdefghijklmnopqrstuvwxyz" ++ ?CRLF ++ "10" ++ ?CRLF
+ ++ "1234567890abcdef" ++ ?CRLF ++ "0" ++ ?CRLF
+ ++ "some-footer:some-value" ++ ?CRLF
+ ++ "another-footer:another-value" ++ ?CRLF ++ ?CRLF,
+ {ok, {_, _}} =
+ http_chunk:decode(list_to_binary(ChunkedBody),
+ ?HTTP_MAX_BODY_SIZE, ?HTTP_MAX_HEADER_SIZE),
+
+ %% Too long body
+ {error,{body_too_big, {max, 10}}} =
+ (catch http_chunk:decode(list_to_binary(ChunkedBody),
+ 10, ?HTTP_MAX_HEADER_SIZE)).
%%-------------------------------------------------------------------------
-http_response(doc) ->
- ["Test httpc_response:parse*. This test case will simulate that the "
+http_response() ->
+ [{doc, "Test httpc_response:parse*. This test case will simulate that the "
"message will be recived a little at the time on a socket and the "
- "package may be broken up into smaller parts at arbitrary point."];
-http_response(suite) ->
- [];
+ "package may be broken up into smaller parts at arbitrary point."}].
http_response(Config) when is_list(Config) ->
HttpHead1 = ["HTTP", "/1.1 ", "20", "0 ", "ok", [?CR, ?LF],
@@ -339,12 +367,10 @@ http_response(Config) when is_list(Config) ->
[<<>>,Length1], HttpBody1)),
ok.
%%-------------------------------------------------------------------------
-http_request(doc) ->
- ["Test httpd_request:parse* This test case will simulate that the "
+http_request() ->
+ [{doc, "Test httpd_request:parse* This test case will simulate that the "
"message will be recived a little at the time on a socket and the "
- "package may be broken up into smaller parts at arbitrary point."];
-http_request(suite) ->
- [];
+ "package may be broken up into smaller parts at arbitrary point."}].
http_request(Config) when is_list(Config) ->
HttpHead = ["GE", "T ", "http://www.erlang", ".org ", "HTTP",
@@ -355,8 +381,13 @@ http_request(Config) when is_list(Config) ->
"http://www.erlang.org",
"HTTP/1.1",
{#http_request_h{host = "www.erlang.org", te = []},
- ["te: ","host:www.erlang.org"]}, <<>>} =
- parse(httpd_request, parse, [?HTTP_MAX_HEADER_SIZE], HttpHead),
+ [{"te", []}, {"host", "www.erlang.org"}]}, <<>>} =
+ parse(httpd_request, parse, [[{max_header, ?HTTP_MAX_HEADER_SIZE},
+ {max_version, ?HTTP_MAX_VERSION_STRING},
+ {max_method, ?HTTP_MAX_METHOD_STRING},
+ {max_content_length, ?HTTP_MAX_CONTENT_LENGTH}
+ ]],
+ HttpHead),
HttpHead1 = ["GET http://www.erlang.org HTTP/1.1" ++
[?CR], [?LF, ?CR, ?LF]],
@@ -364,7 +395,11 @@ http_request(Config) when is_list(Config) ->
"http://www.erlang.org",
"HTTP/1.1",
{#http_request_h{}, []}, <<>>} =
- parse(httpd_request, parse, [?HTTP_MAX_HEADER_SIZE], HttpHead1),
+ parse(httpd_request, parse, [[{max_header, ?HTTP_MAX_HEADER_SIZE},
+ {max_version, ?HTTP_MAX_VERSION_STRING},
+ {max_method, ?HTTP_MAX_METHOD_STRING},
+ {max_content_length, ?HTTP_MAX_CONTENT_LENGTH}
+ ]], HttpHead1),
HttpHead2 = ["GET http://www.erlang.org HTTP/1.1" ++
@@ -373,7 +408,11 @@ http_request(Config) when is_list(Config) ->
"http://www.erlang.org",
"HTTP/1.1",
{#http_request_h{}, []}, <<>>} =
- parse(httpd_request, parse, [?HTTP_MAX_HEADER_SIZE], HttpHead2),
+ parse(httpd_request, parse, [[{max_header, ?HTTP_MAX_HEADER_SIZE},
+ {max_version, ?HTTP_MAX_VERSION_STRING},
+ {max_method, ?HTTP_MAX_METHOD_STRING},
+ {max_content_length, ?HTTP_MAX_CONTENT_LENGTH}
+ ]], HttpHead2),
%% Note the following body is not related to the headers above
HttpBody = ["<HTML>\n<HEAD>\n<TITLE> dummy </TITLE>\n</HEAD>\n<BODY>\n",
@@ -393,15 +432,12 @@ http_request(Config) when is_list(Config) ->
NewBody1 =
binary_to_list(parse
(httpd_request, whole_body,
- [<<>>, Length1], HttpBody1)),
- ok.
+ [<<>>, Length1], HttpBody1)).
%%-------------------------------------------------------------------------
-validate_request_line(doc) ->
- ["Test httpd_request:validate/3. Makes sure you can not get past"
+validate_request_line() ->
+ [{doc, "Test httpd_request:validate/3. Makes sure you can not get past"
" the server_root and that the request is recognized by the server"
- " and protcol version." ];
-validate_request_line(suite) ->
- [];
+ " and protcol version."}].
validate_request_line(Config) when is_list(Config) ->
%% HTTP/0.9 only has GET requests
@@ -454,16 +490,12 @@ validate_request_line(Config) when is_list(Config) ->
NewForbiddenUri1 =
"http://127.0.0.1:8888/../home/ingela/test.html",
{error, {bad_request, {forbidden, NewForbiddenUri1}}} =
- httpd_request:validate("GET", NewForbiddenUri1, "HTTP/1.1"),
-
- ok.
+ httpd_request:validate("GET", NewForbiddenUri1, "HTTP/1.1").
%%-------------------------------------------------------------------------
-check_content_length_encoding(doc) ->
- ["Test http_request:headers/2. Check that the content-length is"
- " encoded even when it is zero." ];
-check_content_length_encoding(suite) ->
- [];
+check_content_length_encoding() ->
+ [{doc, "Test http_request:headers/2. Check that the content-length is"
+ " encoded even when it is zero."}].
check_content_length_encoding(Config) when is_list(Config) ->
%% Check that the content-length is preserved.
@@ -472,16 +504,12 @@ check_content_length_encoding(Config) when is_list(Config) ->
true = (string:str(Header1, "content-length: 123\r\n") > 0),
%% Check that content-length=0 is handled correctly.
Header2 = http_request:http_headers(#http_request_h{'content-length'="0"}),
- true = (string:str(Header2, "content-length: 0\r\n") > 0),
-
- ok.
+ true = (string:str(Header2, "content-length: 0\r\n") > 0).
%%-------------------------------------------------------------------------
-esi_parse_headers(doc) ->
- ["Test httpd_esi:*. All header values are received in the same"
- " erlang message."];
-esi_parse_headers(suite) ->
- [];
+esi_parse_headers() ->
+ [{doc, "Test httpd_esi:*. All header values are received in the same"
+ " erlang message."}].
esi_parse_headers(Config) when is_list(Config) ->
ESIResult = "content-type:text/html\r\ndate:Thu, 28 Oct 2004 07:57:43 "
@@ -508,16 +536,14 @@ esi_parse_headers(Config) when is_list(Config) ->
httpd_esi:handle_headers(Headers2),
{proceed,"/foo/bar.html"} =
- httpd_esi:handle_headers("location:/foo/bar.html\r\n"),
- ok.
+ httpd_esi:handle_headers("location:/foo/bar.html\r\n").
%%--------------------------------------------------------------------
-cgi_parse_headers(doc) ->
- ["Test httpd_cgi:*. This test case will simulate that the "
+cgi_parse_headers() ->
+ [{doc, "Test httpd_cgi:*. This test case will simulate that the "
"message will be recived a little at the time on a socket and the "
- "package may be broken up into smaller parts at arbitrary point."];
-cgi_parse_headers(suite) ->
- [];
+ "package may be broken up into smaller parts at arbitrary point."}].
+
cgi_parse_headers(Config) when is_list(Config) ->
CGIResult = ["content-type:text", "/html\ndate:Thu, 28 Oct 2004 07:57:43 "
@@ -553,26 +579,18 @@ cgi_parse_headers(Config) when is_list(Config) ->
{ok,[{"content-type","text/html"},
{"connection","close"},
{"content-language","en"},
- {"age","4711"}], {200,"ok"}} = httpd_cgi:handle_headers(Headers3),
-
- ok.
-
+ {"age","4711"}], {200,"ok"}} = httpd_cgi:handle_headers(Headers3).
%%-------------------------------------------------------------------------
-is_absolut_uri(doc) ->
- ["Test http_request:is_absolut_uri/1."];
-is_absolut_uri(suite) ->
- [];
+is_absolut_uri() ->
+ [{doc, "Test http_request:is_absolut_uri/1."}].
is_absolut_uri(Config) when is_list(Config) ->
true = http_request:is_absolut_uri("http://www.erlang.org"),
true = http_request:is_absolut_uri("https://www.erlang.org"),
false = http_request:is_absolut_uri("index.html").
-
%%-------------------------------------------------------------------------
-convert_netscapecookie_date(doc) ->
- ["Test http_util:convert_netscapecookie_date/1."];
-convert_netscapecookie_date(suite) ->
- [];
+convert_netscapecookie_date() ->
+ [{doc, "Test http_util:convert_netscapecookie_date/1."}].
convert_netscapecookie_date(Config) when is_list(Config) ->
{{2006,1,6},{8,59,38}} =
http_util:convert_netscapecookie_date("Mon, 06-Jan-2006 08:59:38 GMT"),
@@ -605,9 +623,7 @@ convert_netscapecookie_date(Config) when is_list(Config) ->
{{2006,12,12},{8,59,38}} =
http_util:convert_netscapecookie_date("Sun 12-Dec-06 08:59:38 GMT"),
{{2036,1,1},{8,0,1}} =
- http_util:convert_netscapecookie_date("Tue Jan 01 08:00:01 2036 GMT"),
- ok.
-
+ http_util:convert_netscapecookie_date("Tue Jan 01 08:00:01 2036 GMT").
%%--------------------------------------------------------------------
%%% Internal functions
%%--------------------------------------------------------------------
diff --git a/lib/inets/test/httpc_SUITE.erl b/lib/inets/test/httpc_SUITE.erl
index 0c35f284f7..932567ec55 100644
--- a/lib/inets/test/httpc_SUITE.erl
+++ b/lib/inets/test/httpc_SUITE.erl
@@ -1,18 +1,19 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2004-2013. All Rights Reserved.
+%% Copyright Ericsson AB 2004-2015. 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.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
+%%
+%% http://www.apache.org/licenses/LICENSE-2.0
+%%
+%% Unless required by applicable law or agreed to in writing, software
+%% distributed under the License is distributed on an "AS IS" BASIS,
+%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+%% See the License for the specific language governing permissions and
+%% limitations under the License.
%%
%% %CopyrightEnd%
%%
@@ -27,21 +28,22 @@
-include_lib("kernel/include/file.hrl").
-include_lib("common_test/include/ct.hrl").
-include("inets_test_lib.hrl").
-
+-include("http_internal.hrl").
+-include("httpc_internal.hrl").
%% Note: This directive should only be used in test suites.
-compile(export_all).
-define(URL_START, "http://").
-define(TLS_URL_START, "https://").
-define(NOT_IN_USE_PORT, 8997).
--define(LF, $\n).
--define(HTTP_MAX_HEADER_SIZE, 10240).
+
-record(sslsocket, {fd = nil, pid = nil}).
%%--------------------------------------------------------------------
%% Common Test interface functions -----------------------------------
%%--------------------------------------------------------------------
suite() ->
- [{ct_hooks,[ts_install_cth]}].
+ [{ct_hooks,[ts_install_cth]}
+ ].
all() ->
[
@@ -66,7 +68,9 @@ real_requests()->
head,
get,
post,
+ delete,
post_stream,
+ patch,
async,
pipeline,
persistent_connection,
@@ -91,19 +95,29 @@ only_simulated() ->
[
cookie,
cookie_profile,
+ empty_set_cookie,
+ invalid_set_cookie,
trace,
stream_once,
+ stream_single_chunk,
+ stream_no_length,
+ not_streamed_once,
+ stream_large_not_200_or_206,
no_content_204,
tolerate_missing_CR,
userinfo,
bad_response,
internal_server_error,
invalid_http,
+ invalid_chunk_size,
headers_dummy,
+ headers_with_obs_fold,
empty_response_header,
remote_socket_close,
remote_socket_close_async,
+ process_leak_on_keepalive,
transfer_encoding,
+ transfer_encoding_identity,
redirect_loop,
redirect_moved_permanently,
redirect_multiple_choises,
@@ -124,8 +138,9 @@ misc() ->
%%--------------------------------------------------------------------
init_per_suite(Config) ->
- PrivDir = ?config(priv_dir, Config),
- DataDir = ?config(data_dir, Config),
+ ct:timetrap({seconds, 30}),
+ PrivDir = proplists:get_value(priv_dir, Config),
+ DataDir = proplists:get_value(data_dir, Config),
inets_test_lib:start_apps([inets]),
ServerRoot = filename:join(PrivDir, "server_root"),
DocRoot = filename:join(ServerRoot, "htdocs"),
@@ -134,7 +149,7 @@ init_per_suite(Config) ->
end_per_suite(Config) ->
inets_test_lib:stop_apps([inets]),
- PrivDir = ?config(priv_dir, Config),
+ PrivDir = proplists:get_value(priv_dir, Config),
inets_test_lib:del_dirs(PrivDir),
ok.
@@ -145,6 +160,23 @@ init_per_group(misc = Group, Config) ->
ok = httpc:set_options([{ipfamily, Inet}]),
Config;
+init_per_group(Group, Config0) when Group =:= sim_https; Group =:= https->
+ ct:timetrap({seconds, 30}),
+ start_apps(Group),
+ StartSsl = try ssl:start()
+ catch
+ Error:Reason ->
+ {skip, lists:flatten(io_lib:format("Failed to start apps for https Error=~p Reason=~p", [Error, Reason]))}
+ end,
+ case StartSsl of
+ {error, {already_started, _}} ->
+ do_init_per_group(Group, Config0);
+ ok ->
+ do_init_per_group(Group, Config0);
+ _ ->
+ StartSsl
+ end;
+
init_per_group(Group, Config0) ->
start_apps(Group),
Config = proplists:delete(port, Config0),
@@ -153,7 +185,10 @@ init_per_group(Group, Config0) ->
end_per_group(_, _Config) ->
ok.
-
+do_init_per_group(Group, Config0) ->
+ Config = proplists:delete(port, Config0),
+ Port = server_start(Group, server_config(Group, Config)),
+ [{port, Port} | Config].
%%--------------------------------------------------------------------
init_per_testcase(pipeline, Config) ->
inets:start(httpc, [{profile, pipeline}]),
@@ -167,7 +202,15 @@ init_per_testcase(persistent_connection, Config) ->
{max_keep_alive_length, 3}], persistent_connection),
Config;
-
+init_per_testcase(wait_for_whole_response, Config) ->
+ ct:timetrap({seconds, 60*3}),
+ Config;
+init_per_testcase(Case, Config) when Case == post;
+ Case == delete;
+ Case == post_delete;
+ Case == post_stream ->
+ ct:timetrap({seconds, 30}),
+ Config;
init_per_testcase(_Case, Config) ->
Config.
@@ -225,6 +268,51 @@ post(Config) when is_list(Config) ->
{ok, {{_,504,_}, [_ | _], []}} =
httpc:request(post, {URL, [{"expect","100-continue"}],
"text/plain", "foobar"}, [], []).
+%%--------------------------------------------------------------------
+delete() ->
+ [{"Test http delete request against local server. We do in this case "
+ "only care about the client side of the the delete. The server "
+ "script will not actually use the delete data."}].
+delete(Config) when is_list(Config) ->
+ CGI = case test_server:os_type() of
+ {win32, _} ->
+ "/cgi-bin/cgi_echo.exe";
+ _ ->
+ "/cgi-bin/cgi_echo"
+ end,
+
+ URL = url(group_name(Config), CGI, Config),
+ Body = lists:duplicate(100, "1"),
+
+ {ok, {{_,200,_}, [_ | _], [_ | _]}} =
+ httpc:request(delete, {URL, [{"expect","100-continue"}],
+ "text/plain", Body}, [], []),
+
+ {ok, {{_,504,_}, [_ | _], []}} =
+ httpc:request(delete, {URL, [{"expect","100-continue"}],
+ "text/plain", "foobar"}, [], []).
+
+%%--------------------------------------------------------------------
+patch() ->
+ [{"Test http patch request against local server. We do in this case "
+ "only care about the client side of the the patch. The server "
+ "script will not actually use the patch data."}].
+patch(Config) when is_list(Config) ->
+ CGI = case test_server:os_type() of
+ {win32, _} ->
+ "/cgi-bin/cgi_echo.exe";
+ _ ->
+ "/cgi-bin/cgi_echo"
+ end,
+
+ URL = url(group_name(Config), CGI, Config),
+
+ %% Cgi-script expects the body length to be 100
+ Body = lists:duplicate(100, "1"),
+
+ {ok, {{_,200,_}, [_ | _], [_ | _]}} =
+ httpc:request(patch, {URL, [{"expect","100-continue"}],
+ "text/plain", Body}, [], []).
%%--------------------------------------------------------------------
post_stream() ->
@@ -277,9 +365,9 @@ trace(Config) when is_list(Config) ->
pipeline(Config) when is_list(Config) ->
Request = {url(group_name(Config), "/dummy.html", Config), []},
{ok, _} = httpc:request(get, Request, [], [], pipeline),
-
+
%% Make sure pipeline session is registerd
- test_server:sleep(4000),
+ ct:sleep(4000),
keep_alive_requests(Request, pipeline).
%%--------------------------------------------------------------------
@@ -289,7 +377,7 @@ persistent_connection(Config) when is_list(Config) ->
{ok, _} = httpc:request(get, Request, [], [], persistent),
%% Make sure pipeline session is registerd
- test_server:sleep(4000),
+ ct:sleep(4000),
keep_alive_requests(Request, persistent).
%%-------------------------------------------------------------------------
@@ -311,18 +399,13 @@ async(Config) when is_list(Config) ->
{ok, NewRequestId} =
httpc:request(get, Request, [], [{sync, false}]),
- ok = httpc:cancel_request(NewRequestId),
- receive
- {http, {NewRequestId, _}} ->
- ct:fail(http_cancel_request_failed)
- after 3000 ->
- ok
- end.
+ ok = httpc:cancel_request(NewRequestId).
+
%%-------------------------------------------------------------------------
save_to_file() ->
[{doc, "Test to save the http body to a file"}].
save_to_file(Config) when is_list(Config) ->
- PrivDir = ?config(priv_dir, Config),
+ PrivDir = proplists:get_value(priv_dir, Config),
FilePath = filename:join(PrivDir, "dummy.html"),
URL = url(group_name(Config), "/dummy.html", Config),
Request = {URL, []},
@@ -336,7 +419,7 @@ save_to_file(Config) when is_list(Config) ->
save_to_file_async() ->
[{doc,"Test to save the http body to a file"}].
save_to_file_async(Config) when is_list(Config) ->
- PrivDir = ?config(priv_dir, Config),
+ PrivDir = proplists:get_value(priv_dir, Config),
FilePath = filename:join(PrivDir, "dummy.html"),
URL = url(group_name(Config), "/dummy.html", Config),
Request = {URL, []},
@@ -371,6 +454,37 @@ stream_once(Config) when is_list(Config) ->
Request2 = {url(group_name(Config), "/once_chunked.html", Config), []},
stream_test(Request2, {stream, {self, once}}).
+%%-------------------------------------------------------------------------
+stream_single_chunk() ->
+ [{doc, "Test the option stream for asynchrony requests"}].
+stream_single_chunk(Config) when is_list(Config) ->
+ Request = {url(group_name(Config), "/single_chunk.html", Config), []},
+ stream_test(Request, {stream, self}).
+%%-------------------------------------------------------------------------
+stream_no_length() ->
+ [{doc, "Test the option stream for asynchrony requests with HTTP 1.0 "
+ "body end on closed connection" }].
+stream_no_length(Config) when is_list(Config) ->
+ Request1 = {url(group_name(Config), "/http_1_0_no_length_single.html", Config), []},
+ stream_test(Request1, {stream, self}),
+ Request2 = {url(group_name(Config), "/http_1_0_no_length_multiple.html", Config), []},
+ stream_test(Request2, {stream, self}).
+%%-------------------------------------------------------------------------
+stream_large_not_200_or_206() ->
+ [{doc, "Test the option stream for large responses with status codes "
+ "other than 200 or 206" }].
+stream_large_not_200_or_206(Config) when is_list(Config) ->
+ Request = {url(group_name(Config), "/large_404_response.html", Config), []},
+ {404, _} = not_streamed_test(Request, {stream, self}).
+%%-------------------------------------------------------------------------
+not_streamed_once() ->
+ [{doc, "Test not streamed responses with once streaming"}].
+not_streamed_once(Config) when is_list(Config) ->
+ Request0 = {url(group_name(Config), "/404.html", Config), []},
+ {404, _} = not_streamed_test(Request0, {stream, {self, once}}),
+ Request1 = {url(group_name(Config), "/404_chunked.html", Config), []},
+ {404, _} = not_streamed_test(Request1, {stream, {self, once}}).
+
%%-------------------------------------------------------------------------
redirect_multiple_choises() ->
@@ -522,6 +636,31 @@ cookie_profile(Config) when is_list(Config) ->
inets:stop(httpc, cookie_test).
%%-------------------------------------------------------------------------
+empty_set_cookie() ->
+ [{doc, "Test empty Set-Cookie header."}].
+empty_set_cookie(Config) when is_list(Config) ->
+ ok = httpc:set_options([{cookies, enabled}]),
+
+ Request0 = {url(group_name(Config), "/empty_set_cookie.html", Config), []},
+
+ {ok, {{_,200,_}, [_ | _], [_|_]}}
+ = httpc:request(get, Request0, [], []),
+
+ ok = httpc:set_options([{cookies, disabled}]).
+
+%%-------------------------------------------------------------------------
+invalid_set_cookie(doc) ->
+ ["Test ignoring invalid Set-Cookie header"];
+invalid_set_cookie(Config) when is_list(Config) ->
+ ok = httpc:set_options([{cookies, enabled}]),
+
+ URL = url(group_name(Config), "/invalid_set_cookie.html", Config),
+ {ok, {{_,200,_}, [_|_], [_|_]}} =
+ httpc:request(get, {URL, []}, [], []),
+
+ ok = httpc:set_options([{cookies, disabled}]).
+
+%%-------------------------------------------------------------------------
headers_as_is(doc) ->
["Test the option headers_as_is"];
headers_as_is(Config) when is_list(Config) ->
@@ -616,6 +755,12 @@ transfer_encoding(Config) when is_list(Config) ->
%%-------------------------------------------------------------------------
+transfer_encoding_identity(Config) when is_list(Config) ->
+ URL = url(group_name(Config), "/identity_transfer_encoding.html", Config),
+ {ok, {{_,200,_}, [_|_], "IDENTITY"}} = httpc:request(URL).
+
+%%-------------------------------------------------------------------------
+
empty_response_header() ->
[{doc, "Test the case that the HTTP server does not send any headers. Solves OTP-6830"}].
empty_response_header(Config) when is_list(Config) ->
@@ -679,6 +824,22 @@ invalid_http(Config) when is_list(Config) ->
ct:print("Parse error: ~p ~n", [Reason]).
%%-------------------------------------------------------------------------
+
+invalid_chunk_size(doc) ->
+ ["Test parse error of HTTP chunk size"];
+invalid_chunk_size(suite) ->
+ [];
+invalid_chunk_size(Config) when is_list(Config) ->
+
+ URL = url(group_name(Config), "/invalid_chunk_size.html", Config),
+
+ {error, {chunk_size, _} = Reason} =
+ httpc:request(get, {URL, []}, [], []),
+
+ ct:print("Parse error: ~p ~n", [Reason]).
+
+%%-------------------------------------------------------------------------
+
emulate_lower_versions(doc) ->
[{doc, "Perform request as 0.9 and 1.0 clients."}];
emulate_lower_versions(Config) when is_list(Config) ->
@@ -718,7 +879,7 @@ headers() ->
headers(Config) when is_list(Config) ->
URL = url(group_name(Config), "/dummy.html", Config),
- DocRoot = ?config(doc_root, Config),
+ DocRoot = proplists:get_value(doc_root, Config),
{ok, FileInfo} =
file:read_file_info(filename:join([DocRoot,"dummy.html"])),
@@ -825,6 +986,13 @@ headers_dummy(Config) when is_list(Config) ->
%%-------------------------------------------------------------------------
+headers_with_obs_fold(Config) when is_list(Config) ->
+ Request = {url(group_name(Config), "/obs_folded_headers.html", Config), []},
+ {ok, {{_,200,_}, Headers, [_|_]}} = httpc:request(get, Request, [], []),
+ "a b" = proplists:get_value("folded", Headers).
+
+%%-------------------------------------------------------------------------
+
invalid_headers(Config) ->
Request = {url(group_name(Config), "/dummy.html", Config), [{"cookie", undefined}]},
{error, _} = httpc:request(get, Request, [], []).
@@ -848,6 +1016,33 @@ remote_socket_close_async(Config) when is_list(Config) ->
%%-------------------------------------------------------------------------
+process_leak_on_keepalive(Config) ->
+ {ok, ClosedSocket} = gen_tcp:listen(6666, [{active, false}]),
+ ok = gen_tcp:close(ClosedSocket),
+ Request = {url(group_name(Config), "/dummy.html", Config), []},
+ HttpcHandlers0 = supervisor:which_children(httpc_handler_sup),
+ {ok, {{_, 200, _}, _, Body}} = httpc:request(get, Request, [], []),
+ HttpcHandlers1 = supervisor:which_children(httpc_handler_sup),
+ ChildrenCount = supervisor:count_children(httpc_handler_sup),
+ %% Assuming that the new handler will be selected for keep_alive
+ %% which could not be the case if other handlers existed
+ [{undefined, Pid, worker, [httpc_handler]}] =
+ ordsets:to_list(
+ ordsets:subtract(ordsets:from_list(HttpcHandlers1),
+ ordsets:from_list(HttpcHandlers0))),
+ sys:replace_state(
+ Pid, fun (State) ->
+ Session = element(3, State),
+ setelement(3, State, Session#session{socket=ClosedSocket})
+ end),
+ {ok, {{_, 200, _}, _, Body}} = httpc:request(get, Request, [], []),
+ %% bad handler with the closed socket should get replaced by
+ %% the new one, so children count should stay the same
+ ChildrenCount = supervisor:count_children(httpc_handler_sup),
+ ok.
+
+%%-------------------------------------------------------------------------
+
stream_to_pid(Config) when is_list(Config) ->
ReceiverPid = create_receiver(pid),
Receiver = ReceiverPid,
@@ -1012,14 +1207,27 @@ stream_test(Request, To) ->
ct:fail(Msg)
end,
- Body == binary_to_list(StreamedBody).
+ Body = binary_to_list(StreamedBody).
+
+not_streamed_test(Request, To) ->
+ {ok, {{_,Code,_}, [_ | _], Body}} =
+ httpc:request(get, Request, [], [{body_format, binary}]),
+ {ok, RequestId} =
+ httpc:request(get, Request, [], [{body_format, binary}, {sync, false}, To]),
+
+ receive
+ {http, {RequestId, {{_, Code, _}, _Headers, Body}}} ->
+ {Code, binary_to_list(Body)};
+ {http, Msg} ->
+ ct:fail(Msg)
+ end.
url(http, End, Config) ->
- Port = ?config(port, Config),
+ Port = proplists:get_value(port, Config),
{ok,Host} = inet:gethostname(),
?URL_START ++ Host ++ ":" ++ integer_to_list(Port) ++ End;
url(https, End, Config) ->
- Port = ?config(port, Config),
+ Port = proplists:get_value(port, Config),
{ok,Host} = inet:gethostname(),
?TLS_URL_START ++ Host ++ ":" ++ integer_to_list(Port) ++ End;
url(sim_http, End, Config) ->
@@ -1027,10 +1235,10 @@ url(sim_http, End, Config) ->
url(sim_https, End, Config) ->
url(https, End, Config).
url(http, UserInfo, End, Config) ->
- Port = ?config(port, Config),
+ Port = proplists:get_value(port, Config),
?URL_START ++ UserInfo ++ integer_to_list(Port) ++ End;
url(https, UserInfo, End, Config) ->
- Port = ?config(port, Config),
+ Port = proplists:get_value(port, Config),
?TLS_URL_START ++ UserInfo ++ integer_to_list(Port) ++ End;
url(sim_http, UserInfo, End, Config) ->
url(http, UserInfo, End, Config);
@@ -1038,7 +1246,7 @@ url(sim_https, UserInfo, End, Config) ->
url(https, UserInfo, End, Config).
group_name(Config) ->
- GroupProp = ?config(tc_group_properties, Config),
+ GroupProp = proplists:get_value(tc_group_properties, Config),
proplists:get_value(name, GroupProp).
server_start(sim_http, _) ->
@@ -1060,11 +1268,11 @@ server_start(_, HttpdConfig) ->
proplists:get_value(port, Info).
server_config(http, Config) ->
- ServerRoot = ?config(server_root, Config),
+ ServerRoot = proplists:get_value(server_root, Config),
[{port, 0},
{server_name,"httpc_test"},
{server_root, ServerRoot},
- {document_root, ?config(doc_root, Config)},
+ {document_root, proplists:get_value(doc_root, Config)},
{bind_address, any},
{ipfamily, inet_version()},
{mime_type, "text/plain"},
@@ -1080,11 +1288,13 @@ server_config(_, _) ->
start_apps(https) ->
inets_test_lib:start_apps([crypto, public_key, ssl]);
+start_apps(sim_https) ->
+ inets_test_lib:start_apps([crypto, public_key, ssl]);
start_apps(_) ->
ok.
ssl_config(Config) ->
- DataDir = ?config(data_dir, Config),
+ DataDir = proplists:get_value(data_dir, Config),
[{certfile, filename:join(DataDir, "ssl_server_cert.pem")},
{verify, verify_none}
].
@@ -1149,7 +1359,7 @@ receive_replys([ID|IDs]) ->
{http, {ID, {{_, 200, _}, [_|_], _}}} ->
receive_replys(IDs);
{http, {Other, {{_, 200, _}, [_|_], _}}} ->
- ct:fail({recived_canceld_id, Other})
+ ct:pal({recived_canceld_id, Other})
end.
%% Perform a synchronous stop
@@ -1189,8 +1399,14 @@ dummy_server_init(Caller, ip_comm, Inet, _) ->
{ok, ListenSocket} = gen_tcp:listen(0, [Inet | BaseOpts]),
{ok, Port} = inet:port(ListenSocket),
Caller ! {port, Port},
- dummy_ipcomm_server_loop({httpd_request, parse, [?HTTP_MAX_HEADER_SIZE]},
- [], ListenSocket);
+ dummy_ipcomm_server_loop({httpd_request, parse, [[{max_uri, ?HTTP_MAX_URI_SIZE},
+ {max_header, ?HTTP_MAX_HEADER_SIZE},
+ {max_version,?HTTP_MAX_VERSION_STRING},
+ {max_method, ?HTTP_MAX_METHOD_STRING},
+ {max_content_length, ?HTTP_MAX_CONTENT_LENGTH},
+ {customize, httpd_custom}
+ ]]},
+ [], ListenSocket);
dummy_server_init(Caller, ssl, Inet, SSLOptions) ->
BaseOpts = [binary, {reuseaddr,true}, {active, false} |
@@ -1201,7 +1417,13 @@ dummy_ssl_server_init(Caller, BaseOpts, Inet) ->
{ok, ListenSocket} = ssl:listen(0, [Inet | BaseOpts]),
{ok, {_, Port}} = ssl:sockname(ListenSocket),
Caller ! {port, Port},
- dummy_ssl_server_loop({httpd_request, parse, [?HTTP_MAX_HEADER_SIZE]},
+ dummy_ssl_server_loop({httpd_request, parse, [[{max_uri, ?HTTP_MAX_URI_SIZE},
+ {max_method, ?HTTP_MAX_METHOD_STRING},
+ {max_version,?HTTP_MAX_VERSION_STRING},
+ {max_method, ?HTTP_MAX_METHOD_STRING},
+ {max_content_length, ?HTTP_MAX_CONTENT_LENGTH},
+ {customize, httpd_custom}
+ ]]},
[], ListenSocket).
dummy_ipcomm_server_loop(MFA, Handlers, ListenSocket) ->
@@ -1231,6 +1453,7 @@ dummy_ssl_server_loop(MFA, Handlers, ListenSocket) ->
From ! {stopped, self()}
after 0 ->
{ok, Socket} = ssl:transport_accept(ListenSocket),
+ ok = ssl:ssl_accept(Socket, infinity),
HandlerPid = dummy_request_handler(MFA, Socket),
ssl:controlling_process(Socket, HandlerPid),
HandlerPid ! ssl_controller,
@@ -1277,10 +1500,22 @@ handle_request(Module, Function, Args, Socket) ->
stop ->
stop;
<<>> ->
- {httpd_request, parse, [[<<>>, ?HTTP_MAX_HEADER_SIZE]]};
+ {httpd_request, parse, [[{max_uri,?HTTP_MAX_URI_SIZE},
+ {max_header, ?HTTP_MAX_HEADER_SIZE},
+ {max_version,?HTTP_MAX_VERSION_STRING},
+ {max_method, ?HTTP_MAX_METHOD_STRING},
+ {max_content_length, ?HTTP_MAX_CONTENT_LENGTH},
+ {customize, httpd_custom}
+ ]]};
Data ->
handle_request(httpd_request, parse,
- [Data |[?HTTP_MAX_HEADER_SIZE]], Socket)
+ [Data, [{max_uri, ?HTTP_MAX_URI_SIZE},
+ {max_header, ?HTTP_MAX_HEADER_SIZE},
+ {max_version,?HTTP_MAX_VERSION_STRING},
+ {max_method, ?HTTP_MAX_METHOD_STRING},
+ {max_content_length, ?HTTP_MAX_CONTENT_LENGTH},
+ {customize, httpd_custom}
+ ]], Socket)
end;
NewMFA ->
NewMFA
@@ -1370,7 +1605,7 @@ dummy_ssl_server_hang_loop(_) ->
ensure_host_header_with_port([]) ->
false;
-ensure_host_header_with_port(["host: " ++ Host| _]) ->
+ensure_host_header_with_port([{"host", Host}| _]) ->
case string:tokens(Host, [$:]) of
[_ActualHost, _Port] ->
true;
@@ -1382,7 +1617,7 @@ ensure_host_header_with_port([_|T]) ->
auth_header([]) ->
auth_header_not_found;
-auth_header(["authorization:" ++ Value | _]) ->
+auth_header([{"authorization", Value} | _]) ->
{ok, string:strip(Value)};
auth_header([_ | Tail]) ->
auth_header(Tail).
@@ -1399,7 +1634,7 @@ handle_auth("Basic " ++ UserInfo, Challange, DefaultResponse) ->
check_cookie([]) ->
ct:fail(no_cookie_header);
-check_cookie(["cookie:" ++ _Value | _]) ->
+check_cookie([{"cookie", _} | _]) ->
ok;
check_cookie([_Head | Tail]) ->
check_cookie(Tail).
@@ -1518,6 +1753,11 @@ handle_uri(_,"/307.html",Port,_,Socket,_) ->
"Content-Length:" ++ integer_to_list(length(Body))
++ "\r\n\r\n" ++ Body;
+handle_uri(_,"/404.html",_,_,_,_) ->
+ "HTTP/1.1 404 not found\r\n" ++
+ "Content-Length:14\r\n\r\n" ++
+ "Page not found";
+
handle_uri(_,"/500.html",_,_,_,_) ->
"HTTP/1.1 500 Internal Server Error\r\n" ++
"Content-Length:47\r\n\r\n" ++
@@ -1591,6 +1831,13 @@ handle_uri(_,"/dummy_headers.html",_,_,Socket,_) ->
send(Socket, http_chunk:encode("obar</BODY></HTML>")),
http_chunk:encode_last();
+handle_uri(_,"/obs_folded_headers.html",_,_,_,_) ->
+ "HTTP/1.1 200 ok\r\n"
+ "Content-Length:5\r\n"
+ "Folded: a\r\n"
+ " b\r\n\r\n"
+ "Hello";
+
handle_uri(_,"/capital_transfer_encoding.html",_,_,Socket,_) ->
Head = "HTTP/1.1 200 ok\r\n" ++
"Transfer-Encoding:Chunked\r\n\r\n",
@@ -1599,6 +1846,13 @@ handle_uri(_,"/capital_transfer_encoding.html",_,_,Socket,_) ->
send(Socket, http_chunk:encode("obar</BODY></HTML>")),
http_chunk:encode_last();
+handle_uri(_,"/identity_transfer_encoding.html",_,_,_,_) ->
+ "HTTP/1.0 200 OK\r\n"
+ "Transfer-Encoding:identity\r\n"
+ "Content-Length:8\r\n"
+ "\r\n"
+ "IDENTITY";
+
handle_uri(_,"/cookie.html",_,_,_,_) ->
"HTTP/1.1 200 ok\r\n" ++
"set-cookie:" ++ "test_cookie=true; path=/;" ++
@@ -1606,6 +1860,20 @@ handle_uri(_,"/cookie.html",_,_,_,_) ->
"Content-Length:32\r\n\r\n"++
"<HTML><BODY>foobar</BODY></HTML>";
+handle_uri(_,"/empty_set_cookie.html",_,_,_,_) ->
+ "HTTP/1.1 200 ok\r\n" ++
+ "set-cookie: \r\n" ++
+ "Content-Length:32\r\n\r\n"++
+ "<HTML><BODY>foobar</BODY></HTML>";
+
+handle_uri(_,"/invalid_set_cookie.html",_,_,_,_) ->
+ "HTTP/1.1 200 ok\r\n" ++
+ "set-cookie: =\r\n" ++
+ "set-cookie: name=\r\n" ++
+ "set-cookie: name-or-value\r\n" ++
+ "Content-Length:32\r\n\r\n"++
+ "<HTML><BODY>foobar</BODY></HTML>";
+
handle_uri(_,"/missing_crlf.html",_,_,_,_) ->
"HTTP/1.1 200 ok" ++
"Content-Length:32\r\n" ++
@@ -1625,20 +1893,68 @@ handle_uri(_,"/once_chunked.html",_,_,Socket,_) ->
http_chunk:encode("obar</BODY></HTML>")),
http_chunk:encode_last();
+handle_uri(_,"/404_chunked.html",_,_,Socket,_) ->
+ Head = "HTTP/1.1 404 not found\r\n" ++
+ "Transfer-Encoding:Chunked\r\n\r\n",
+ send(Socket, Head),
+ send(Socket, http_chunk:encode("<HTML><BODY>Not ")),
+ send(Socket,
+ http_chunk:encode("found</BODY></HTML>")),
+ http_chunk:encode_last();
+
+handle_uri(_,"/single_chunk.html",_,_,Socket,_) ->
+ Chunk = "HTTP/1.1 200 ok\r\n" ++
+ "Transfer-Encoding:Chunked\r\n\r\n" ++
+ http_chunk:encode("<HTML><BODY>fo") ++
+ http_chunk:encode("obar</BODY></HTML>") ++
+ http_chunk:encode_last(),
+ send(Socket, Chunk);
+
+handle_uri(_,"/http_1_0_no_length_single.html",_,_,Socket,_) ->
+ Body = "HTTP/1.0 200 ok\r\n"
+ "Content-type:text/plain\r\n\r\n"
+ "single packet",
+ send(Socket, Body),
+ close(Socket);
+
+handle_uri(_,"/http_1_0_no_length_multiple.html",_,_,Socket,_) ->
+ Head = "HTTP/1.0 200 ok\r\n"
+ "Content-type:text/plain\r\n\r\n"
+ "multiple packets, ",
+ send(Socket, Head),
+ %% long body to make sure it will be sent in multiple tcp packets
+ send(Socket, string:copies("other multiple packets ", 200)),
+ close(Socket);
+
+handle_uri(_,"/large_404_response.html",_,_,Socket,_) ->
+ %% long body to make sure it will be sent in multiple tcp packets
+ Body = string:copies("other multiple packets ", 200),
+ Head = io_lib:format("HTTP/1.1 404 not found\r\n"
+ "Content-length: ~B\r\n"
+ "Content-type: text/plain\r\n\r\n",
+ [length(Body)]),
+ send(Socket, Head),
+ send(Socket, Body),
+ close(Socket);
+
handle_uri(_,"/once.html",_,_,Socket,_) ->
Head = "HTTP/1.1 200 ok\r\n" ++
"Content-Length:32\r\n\r\n",
send(Socket, Head),
send(Socket, "<HTML><BODY>fo"),
- test_server:sleep(1000),
+ ct:sleep(1000),
send(Socket, "ob"),
- test_server:sleep(1000),
+ ct:sleep(1000),
send(Socket, "ar</BODY></HTML>");
handle_uri(_,"/invalid_http.html",_,_,_,_) ->
"HTTP/1.1 301\r\nDate:Sun, 09 Dec 2007 13:04:18 GMT\r\n" ++
"Transfer-Encoding:chunked\r\n\r\n";
+handle_uri(_,"/invalid_chunk_size.html",_,_,_,_) ->
+ "HTTP/1.1 200 ok\r\n" ++
+ "Transfer-Encoding:chunked\r\n\r\nåäö\r\n";
+
handle_uri(_,"/missing_reason_phrase.html",_,_,_,_) ->
"HTTP/1.1 200\r\n" ++
"Content-Length: 32\r\n\r\n"
@@ -1764,7 +2080,7 @@ run_clients(NumClients, ServerPort, SeqNumServer) ->
end
end),
MRef = erlang:monitor(process, Pid),
- timer:sleep(10 + random:uniform(1334)),
+ timer:sleep(10 + rand:uniform(1334)),
{Id, Pid, MRef}
end,
lists:seq(1, NumClients)).
@@ -1772,12 +2088,13 @@ run_clients(NumClients, ServerPort, SeqNumServer) ->
wait4clients([], _Timeout) ->
ok;
wait4clients(Clients, Timeout) when Timeout > 0 ->
- Time = now_ms(),
+ Time = erlang:monotonic_time(),
+
receive
{'DOWN', _MRef, process, Pid, normal} ->
{value, {Id, _, _}} = lists:keysearch(Pid, 2, Clients),
NewClients = lists:keydelete(Id, 1, Clients),
- wait4clients(NewClients, Timeout - (now_ms() - Time));
+ wait4clients(NewClients, Timeout - inets_lib:millisec_passed(Time));
{'DOWN', _MRef, process, Pid, Reason} ->
{value, {Id, _, _}} = lists:keysearch(Pid, 2, Clients),
ct:fail({bad_client_termination, Id, Reason})
@@ -1852,7 +2169,7 @@ slowly_send_response(CSock, Answer) ->
[length(Answer), Answer])),
lists:foreach(
fun(Char) ->
- timer:sleep(random:uniform(500)),
+ timer:sleep(rand:uniform(500)),
gen_tcp:send(CSock, <<Char>>)
end,
Response).
@@ -1870,15 +2187,10 @@ parse_connection_type(Request) ->
"keep-alive" -> keep_alive
end.
-%% Time in milli seconds
-now_ms() ->
- {A,B,C} = erlang:now(),
- A*1000000000+B*1000+(C div 1000).
-
set_random_seed() ->
- {_, _, Micros} = now(),
- A = erlang:phash2([make_ref(), self(), Micros]),
- random:seed(A, A, A).
+ Unique = erlang:unique_integer(),
+ A = erlang:phash2([make_ref(), self(), Unique]),
+ rand:seed(exsplus, {A, A, A}).
otp_8739(doc) ->
diff --git a/lib/inets/test/httpc_SUITE_data/ssl_client_cert.pem b/lib/inets/test/httpc_SUITE_data/ssl_client_cert.pem
index f274d2021d..427447958d 100644
--- a/lib/inets/test/httpc_SUITE_data/ssl_client_cert.pem
+++ b/lib/inets/test/httpc_SUITE_data/ssl_client_cert.pem
@@ -1,22 +1,31 @@
-----BEGIN RSA PRIVATE KEY-----
-MIIBOwIBAAJBANz7eFvORmJDi1XJMM2U3uHC5wmp/DXTLMw08XaEvtZ73wgVg84E
-V0oyX3Kh1thRE3Hch9AyrHjgpizCj9/Ra38CAwEAAQJACzpz2SZYCTIpaEh6xFdm
-I86FcsZCXHHIeu/NvRntoHQ+nfM7Np379+z6XNJWIcWh/QgG/jNJalR1BO+eyc6/
-YQIhAP3m8M0LDxJwSgHFtGAGatQqaqw9l48Kq5xdMFqvdpiHAiEA3s7lld6yCJYu
-6q7fZjTH+eKUwgg0vpgJutP7Fsok60kCIHHesQBEhW3vjkFdOZgXSLH+k/jLZr1w
-O6bU5GrHZpjhAiEAyTvGYcjDtTunXjDY9l+fadK6FlEBCk8ZIpNIiTnDhHkCIQDr
-QxxLLuNHRj8iWNbuVVZ99SJy8zC33pMgPFaFKaZesQ==
+MIICXQIBAAKBgQCTFBPkOO98fDY3j6MIxIGKp+rampfIay50Lx4+EnCnRSSVwC+n
+0VVmP7V5SGFJpuXJzN0hvqPUWOOjiMTNlNRaGy0pqu2oMXWAPLOxHWL1wT53h2Zr
+3FUNU/N0Rvnkttse1KZJ9uYCLKUiuXXsv2rR62nH3OhRIiBHSAcSv0NRWwIDAQAB
+AoGACdIVYe/LTeydUihtInC8lZ2QuPgJmoBNocRjqJFipEihoL4scHAx25n1bBvB
+I0HZphffzBkGp28oBAtl2LRPWXqu527unc/RWRfLMqSK1xNSq1DxD1a30zkrZPna
+QiV65vEJuNSJTtlDy/Zqc/BVZXCpxWlzYQedZgkmf0Qse8ECQQCmaz02Yur8zC9f
+eSQKU5OSzGw3bSIumEzziCfHdTheK6MEoccf5TCAyLXhZwA7QlKja4tFXfeyVxws
+/LlnUJN9AkEA4j+xnOeYUyGKXL5i+BAbnqpI4MzPiq+IoCYkaRlD/wAws24r5HNI
+ZQmEHWqD/NNzOf/A2XuyLtMiTGJPW/DftwJBAKKpJP6Ytuh6xz8BUCnLwO12Y7vV
+LtjuQiCzD3aUa5EYA9HOMqxJPxxRkf0LyR0i2VUkE8+sZiPpov+R0cJa7p0CQQCj
+40GUiArGRSiF7/+e84QeVfl+pb29F1QftiFv5DZmFEwy3Z572KpbTh5edJbxYHY6
+UDHxGHJFCvnwXNJhpkVXAkBJqfEfiMJ3Q/E5Gpf3sQizacouW92iiN8ojlF1oB80
+t34RysJH7SgI3gdMhTribCo2UUaV0StjR6yodPN+TB2J
-----END RSA PRIVATE KEY-----
-----BEGIN CERTIFICATE-----
-MIIB7jCCAZgCAQAwDQYJKoZIhvcNAQEEBQAwgYExCzAJBgNVBAYTAlNFMRIwEAYD
-VQQHEwlTdG9ja2hvbG0xETAPBgNVBAoTCEVyaWNzc29uMQwwCgYDVQQLEwNFVFgx
-FjAUBgNVBAMTDUhlbGVuIEFpcml5YW4xJTAjBgkqhkiG9w0BCQEWFmhlbGVuQGVy
-aXguZXJpY3Nzb24uc2UwHhcNOTcwNzI4MDcxNDI1WhcNOTgxMjEwMDcxNDI1WjCB
-gTELMAkGA1UEBhMCU0UxEjAQBgNVBAcTCVN0b2NraG9sbTERMA8GA1UEChMIRXJp
-Y3Nzb24xDDAKBgNVBAsTA0VUWDEWMBQGA1UEAxMNSGVsZW4gQWlyaXlhbjElMCMG
-CSqGSIb3DQEJARYWaGVsZW5AZXJpeC5lcmljc3Nvbi5zZTBcMA0GCSqGSIb3DQEB
-AQUAA0sAMEgCQQDc+3hbzkZiQ4tVyTDNlN7hwucJqfw10yzMNPF2hL7We98IFYPO
-BFdKMl9yodbYURNx3IfQMqx44KYswo/f0Wt/AgMBAAEwDQYJKoZIhvcNAQEEBQAD
-QQC2++hLIaQJ4ChCjFE9UCfXO9cZ3Vq/FT9VjE+G4MRBDo4LQ5mBKNXcPF6EFZmi
-7XrlvopXkVPlRguTi2SLRPkY
+MIIChzCCAfCgAwIBAgIGAIsapa8BMA0GCSqGSIb3DQEBBQUAMHoxDjAMBgNVBAMT
+BW90cENBMSAwHgYJKoZIhvcNAQkBFhF0ZXN0ZXJAZXJsYW5nLm9yZzESMBAGA1UE
+BxMJU3RvY2tob2xtMQswCQYDVQQGEwJTRTEPMA0GA1UEChMGZXJsYW5nMRQwEgYD
+VQQLEwt0ZXN0aW5nIGRlcDAiGA8yMDEwMDkwMTAwMDAwMFoYDzIwMjUwODI4MDAw
+MDAwWjB7MQ8wDQYDVQQDEwZjbGllbnQxIDAeBgkqhkiG9w0BCQEWEXRlc3RlckBl
+cmxhbmcub3JnMRIwEAYDVQQHEwlTdG9ja2hvbG0xCzAJBgNVBAYTAlNFMQ8wDQYD
+VQQKEwZlcmxhbmcxFDASBgNVBAsTC3Rlc3RpbmcgZGVwMIGfMA0GCSqGSIb3DQEB
+AQUAA4GNADCBiQKBgQCTFBPkOO98fDY3j6MIxIGKp+rampfIay50Lx4+EnCnRSSV
+wC+n0VVmP7V5SGFJpuXJzN0hvqPUWOOjiMTNlNRaGy0pqu2oMXWAPLOxHWL1wT53
+h2Zr3FUNU/N0Rvnkttse1KZJ9uYCLKUiuXXsv2rR62nH3OhRIiBHSAcSv0NRWwID
+AQABoxMwETAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEBBQUAA4GBAG8t6f1A
+PF7xayGxtUpG2r6W5ETylC3ZIKPS2kfJk9aYi7AZNTp7/xTU6SgqvFBN8aBPzxCD
+4jHrSNC8DSb4X1x9uimarb6qdZDHEdij+DRAd2eygJHZxEf7+8B4Fx34thQeU9hZ
+S1Izke5AlsyFMkvB7h0anE4k9BfuU70vl6v5
-----END CERTIFICATE-----
diff --git a/lib/inets/test/httpc_SUITE_data/ssl_server_cert.pem b/lib/inets/test/httpc_SUITE_data/ssl_server_cert.pem
index f01b6c992b..4aac86db49 100644
--- a/lib/inets/test/httpc_SUITE_data/ssl_server_cert.pem
+++ b/lib/inets/test/httpc_SUITE_data/ssl_server_cert.pem
@@ -1,22 +1,31 @@
-----BEGIN RSA PRIVATE KEY-----
-MIIBOQIBAAJBAMe2WhP6s+JeKOwWPEjI9susfN4Vjn2dd1X4QUlOETcWVLoF916m
-M4JU+ms7+ciMR8GRNCsIeqZGY8/GSqm74ccCAwEAAQJAF08YKlbLYfM9cXiS5qfV
-7iWemUkIzW5wfC8yZ3zeE4Cp6R9ViUfs/dadQ/23Cw0Bpo2t8UdTUdCa4KpmqOem
-cQIhAOnxTWZ5eo6h6PXDp7L5FZUACg8+wT3qf5f2is2mbSZPAiEA2orUY8JZDTSk
-Rm7q9WxLiLNtORsXdTCmnCWhqBOYpwkCIErdowRxScxNekz0IT3AQqzdR1rbnWHg
-IpcSGhd39CQ3AiA1XvQxjLP8wp9fyBS/bPwhXVhOOuyGpSP7PEF3b5m3KQIgGQWc
-/a5wuWx3pc3mLx0ILwNoJr2ubFEuW1PJPsPJPv0=
+MIICXQIBAAKBgQCf4Htxr99lLs5W8QQw7jdakqyAkIjOW4aqH8sr4va4SvZ9Adq6
+7k8jMHefCVZo+F8x4cwsBgB4aWzFIGBnvFTi6YsH27XW7f9O9IPCej8fdhRZ4UAt
+NHa253buOWpDGla2JmIdkmfFvXFJycMIKbG5tYilVXoWKBMKmCwWaXz0nQIDAQAB
+AoGAQIlma0r6W6bcRj4+Wd4fXCFvHuq5Psu1fYEeC5Yvz8761xVjjSfbrDHJZ9pm
+FjOEgedK+s5lbDXqYVyjbdyZSugStBRocSmbG8SQHcAsxR2ZIkNzX2hYzB+lslWo
+T3YJojDyB134O7XJznCu+ZFXP86jyJ1JT6k6a+OIHcwnJ+ECQQDYn57dY4Px3mEd
+VBLStN3YkRF5oFyT+xk7IaKeLLB6n4gCnoVbBoHut7PFbPYPzoNzEwPk3MQKDIHb
+Kig3S5CpAkEAvPA1VmoJWAlN6kUi+F2L8HXEArzE8x7vwdsslrwMKUe4dFS+ZC/7
+5iDOaxcZ7TYkCgwzBt341++DCgP6j3fY1QJBALB6AcOcwi52m6l4B8mu3ZkEPjdX
+BHTuONTqhv/TqoaLlxODL2NDvvDKqeMp7KBd/srt79swW2lQXS4+fvrlTdkCQQCm
+zxj4O1QWkthkfje6ubSkTwUIOatUzrp1F9GNH2dJRtX2dx9FCwxGCC7WY6XzRXqa
+GF0wsedSllbGD+82nWQlAkAicMGqCqRq4hKR/cVmFatOqKVWCVkx6OFF2FhuiI5Z
+h5eIOPGCt8dVRs1P9DNSld/D98Sfm65m85z8BtXovvYV
-----END RSA PRIVATE KEY-----
-----BEGIN CERTIFICATE-----
-MIIB7jCCAZgCAQAwDQYJKoZIhvcNAQEEBQAwgYExCzAJBgNVBAYTAlNFMRIwEAYD
-VQQHEwlTdG9ja2hvbG0xETAPBgNVBAoTCEVyaWNzc29uMQwwCgYDVQQLEwNFVFgx
-FjAUBgNVBAMTDUhlbGVuIEFpcml5YW4xJTAjBgkqhkiG9w0BCQEWFmhlbGVuQGVy
-aXguZXJpY3Nzb24uc2UwHhcNOTcwNzI4MDcyMTAwWhcNOTgxMjEwMDcyMTAwWjCB
-gTELMAkGA1UEBhMCU0UxEjAQBgNVBAcTCVN0b2NraG9sbTERMA8GA1UEChMIRXJp
-Y3Nzb24xDDAKBgNVBAsTA0VUWDEWMBQGA1UEAxMNSGVsZW4gQWlyaXlhbjElMCMG
-CSqGSIb3DQEJARYWaGVsZW5AZXJpeC5lcmljc3Nvbi5zZTBcMA0GCSqGSIb3DQEB
-AQUAA0sAMEgCQQDHtloT+rPiXijsFjxIyPbLrHzeFY59nXdV+EFJThE3FlS6Bfde
-pjOCVPprO/nIjEfBkTQrCHqmRmPPxkqpu+HHAgMBAAEwDQYJKoZIhvcNAQEEBQAD
-QQCnU1TkxmfbLdUwjdECb5x9QHCevAR7AmTms4Csn2oOEyPX+bgF2d94xhrV1sxO
-Rs0yigk1PtN17Ci0Dey0LYkR
+MIIChzCCAfCgAwIBAgIGANUxXM9BMA0GCSqGSIb3DQEBBQUAMHoxDjAMBgNVBAMT
+BW90cENBMSAwHgYJKoZIhvcNAQkBFhF0ZXN0ZXJAZXJsYW5nLm9yZzESMBAGA1UE
+BxMJU3RvY2tob2xtMQswCQYDVQQGEwJTRTEPMA0GA1UEChMGZXJsYW5nMRQwEgYD
+VQQLEwt0ZXN0aW5nIGRlcDAiGA8yMDEwMDkwMTAwMDAwMFoYDzIwMjUwODI4MDAw
+MDAwWjB7MQ8wDQYDVQQDEwZzZXJ2ZXIxIDAeBgkqhkiG9w0BCQEWEXRlc3RlckBl
+cmxhbmcub3JnMRIwEAYDVQQHEwlTdG9ja2hvbG0xCzAJBgNVBAYTAlNFMQ8wDQYD
+VQQKEwZlcmxhbmcxFDASBgNVBAsTC3Rlc3RpbmcgZGVwMIGfMA0GCSqGSIb3DQEB
+AQUAA4GNADCBiQKBgQCf4Htxr99lLs5W8QQw7jdakqyAkIjOW4aqH8sr4va4SvZ9
+Adq67k8jMHefCVZo+F8x4cwsBgB4aWzFIGBnvFTi6YsH27XW7f9O9IPCej8fdhRZ
+4UAtNHa253buOWpDGla2JmIdkmfFvXFJycMIKbG5tYilVXoWKBMKmCwWaXz0nQID
+AQABoxMwETAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEBBQUAA4GBAGF5Pfwk
+QDdwJup/mVITPxbBls4Yl7anDooUQsq8066lA1g54H/PRfXscGkyCFGh1ifXvf1L
+psMRoBAdDHL/wSJplk3rRavkC94eBgnTFZmfKL6844g1j53yameiYL8IEVExYMBg
+/XGyc0qwq57WT8B/K4aElrvlBlQ0wF3wN54M
-----END CERTIFICATE-----
diff --git a/lib/inets/test/httpc_cookie_SUITE.erl b/lib/inets/test/httpc_cookie_SUITE.erl
index 80f43ec236..8140967bca 100644
--- a/lib/inets/test/httpc_cookie_SUITE.erl
+++ b/lib/inets/test/httpc_cookie_SUITE.erl
@@ -1,35 +1,30 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2005-2013. All Rights Reserved.
+%% Copyright Ericsson AB 2005-2016. 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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% 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.
+%% http://www.apache.org/licenses/LICENSE-2.0
+%%
+%% Unless required by applicable law or agreed to in writing, software
+%% distributed under the License is distributed on an "AS IS" BASIS,
+%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+%% See the License for the specific language governing permissions and
+%% limitations under the License.
%%
%% %CopyrightEnd%
%%
%%
-module(httpc_cookie_SUITE).
--include_lib("test_server/include/test_server.hrl").
+-include_lib("common_test/include/ct.hrl").
-include_lib("stdlib/include/ms_transform.hrl").
-%% Test server specific exports
--export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1, init_per_group/2,end_per_group/2, init_per_testcase/2, end_per_testcase/2]).
-
-%% Test cases must be exported.
--export([session_cookies_only/1, netscape_cookies/1,
- cookie_cancel/1, cookie_expires/1, persistent_cookie/1,
- domain_cookie/1, secure_cookie/1, update_cookie/1,
- update_cookie_session/1, cookie_attributes/1]).
+%% Note: This directive should only be used in test suites.
+-compile(export_all).
-define(URL, "http://myhost.cookie.test.org").
-define(URL_DOMAIN, "http://myhost2.cookie.test.org").
@@ -37,86 +32,10 @@
%% Test server callback functions
-%%--------------------------------------------------------------------
-%% Function: init_per_testcase(TestCase, 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.
-%% Description: Initiation before each test case
-%%--------------------------------------------------------------------
-init_per_testcase(session_cookies_only = Case, Config0) ->
- tsp("init_per_testcase(~p) -> entry with"
- "~n Config0: ~p", [Case, Config0]),
- Config = init_workdir(Case, Config0),
- application:start(inets),
- httpc:set_options([{cookies, verify}]),
- watch_dog(Config);
-
-init_per_testcase(Case, Config0) ->
- tsp("init_per_testcase(~p) -> entry with"
- "~n Config0: ~p", [Case, Config0]),
- Config = init_workdir(Case, Config0),
- CaseDir = ?config(case_top_dir, Config),
- application:load(inets),
- application:set_env(inets, services, [{httpc, {default, CaseDir}}]),
- application:start(inets),
- httpc:set_options([{cookies, verify}]),
- watch_dog(Config).
-
-watch_dog(Config) ->
- Dog = test_server:timetrap(inets_test_lib:minutes(10)),
- NewConfig = lists:keydelete(watchdog, 1, Config),
- [{watchdog, Dog} | NewConfig].
-
-init_workdir(Case, Config) ->
- PrivDir = ?config(priv_dir, Config),
- SuiteTopDir = filename:join(PrivDir, ?MODULE),
- case file:make_dir(SuiteTopDir) of
- ok ->
- ok;
- {error, eexist} ->
- ok;
- Error ->
- tsf({failed_creating_subsuite_top_dir, Error})
- end,
-
- CaseTopDir = filename:join(SuiteTopDir, Case),
- ?line ok = file:make_dir(CaseTopDir),
- [{suite_top_dir, SuiteTopDir},
- {case_top_dir, CaseTopDir} | Config].
-
-
-%%--------------------------------------------------------------------
-%% Function: end_per_testcase(TestCase, 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) ->
- tsp("end_per_testcase(~p) -> entry with"
- "~n Config: ~p", [Case, Config]),
- application:stop(inets),
- Dog = ?config(watchdog, Config),
- test_server:timetrap_cancel(Dog),
- ok.
-
-%%--------------------------------------------------------------------
-%% Function: all(Clause) -> TestCases
-%% Clause - atom() - suite | doc
-%% TestCases - [Case]
-%% Case - atom()
-%% Name of a test case.
-%% Description: Returns a list of all test cases in this test suite
-%%--------------------------------------------------------------------
-suite() -> [{ct_hooks,[ts_install_cth]}].
+suite() ->
+ [{ct_hooks,[ts_install_cth]},
+ {timetrap,{seconds,15}}
+ ].
all() ->
[
@@ -147,17 +66,55 @@ init_per_group(_GroupName, Config) ->
end_per_group(_GroupName, Config) ->
Config.
+init_per_testcase(session_cookies_only = Case, Config0) ->
+ Config = init_workdir(Case, Config0),
+ application:start(inets),
+ httpc:set_options([{cookies, verify}]),
+ Config;
+init_per_testcase(cookie_expires = Case, Config0) ->
+ Config = init_workdir(Case, Config0),
+ CaseDir = proplists:get_value(case_top_dir, Config),
+ application:start(inets),
+ application:set_env(inets, services, [{httpc, {default, CaseDir}}]),
+ application:start(inets),
+ httpc:set_options([{cookies, verify}]),
+ Config;
+init_per_testcase(Case, Config0) ->
+ Config = init_workdir(Case, Config0),
+ CaseDir = proplists:get_value(case_top_dir, Config),
+ application:load(inets),
+ application:set_env(inets, services, [{httpc, {default, CaseDir}}]),
+ application:start(inets),
+ httpc:set_options([{cookies, verify}]),
+ Config.
+
+init_workdir(Case, Config) ->
+ PrivDir = proplists:get_value(priv_dir, Config),
+ SuiteTopDir = filename:join(PrivDir, ?MODULE),
+ case file:make_dir(SuiteTopDir) of
+ ok ->
+ ok;
+ {error, eexist} ->
+ ok;
+ Error ->
+ ct:fail({failed_creating_subsuite_top_dir, Error})
+ end,
+
+ CaseTopDir = filename:join(SuiteTopDir, Case),
+ ok = file:make_dir(CaseTopDir),
+ [{suite_top_dir, SuiteTopDir},
+ {case_top_dir, CaseTopDir} | Config].
+
+end_per_testcase(_, _) ->
+ application:stop(inets).
+
%% Test cases starts here.
%%--------------------------------------------------------------------
-session_cookies_only(doc) ->
- ["Test that all cookies are handled as session cookies if there"
- "does not exist a directory to save presitent cookies in."];
-session_cookies_only(suite) ->
- [];
+session_cookies_only() ->
+ [{doc, "Test that all cookies are handled as session cookies if there"
+ "does not exist a directory to save presitent cookies in."}].
session_cookies_only(Config) when is_list(Config) ->
- tsp("session_cookies_only -> Cookies 1: ~p", [httpc:which_cookies()]),
-
SetCookieHeaders = [{"set-cookie", "test_cookie=true; path=/;"
";max-age=60000"}],
httpc:store_cookies(SetCookieHeaders, ?URL),
@@ -165,36 +122,22 @@ session_cookies_only(Config) when is_list(Config) ->
httpc:cookie_header(?URL),
application:stop(inets),
application:start(inets),
- {"cookie", ""} = httpc:cookie_header(?URL),
+ {"cookie", ""} = httpc:cookie_header(?URL).
- tsp("session_cookies_only -> Cookies 2: ~p", [httpc:which_cookies()]),
- ok.
-
-netscape_cookies(doc) ->
- ["Test that the old (original) format of cookies are accepted."];
-netscape_cookies(suite) ->
- [];
+netscape_cookies() ->
+ [{doc, "Test that the old (original) format of cookies are accepted."}].
netscape_cookies(Config) when is_list(Config) ->
- tsp("netscape_cookies -> Cookies 1: ~p", [httpc:which_cookies()]),
-
Expires = future_netscape_date(),
SetCookieHeaders = [{"set-cookie", "test_cookie=true; path=/; "
"expires=" ++ Expires}],
httpc:store_cookies(SetCookieHeaders, ?URL),
{"cookie", "$Version=0; test_cookie=true; $Path=/"} =
- httpc:cookie_header(?URL),
-
- tsp("netscape_cookies -> Cookies 2: ~p", [httpc:which_cookies()]),
- ok.
+ httpc:cookie_header(?URL).
-cookie_cancel(doc) ->
- ["A cookie can be canceld by sending the same cookie with max-age=0 "
- "this test cheks that cookie is canceled."];
-cookie_cancel(suite) ->
- [];
+cookie_cancel() ->
+ [{doc, "A cookie can be canceld by sending the same cookie with max-age=0 "
+ "this test cheks that cookie is canceled."}].
cookie_cancel(Config) when is_list(Config) ->
- tsp("cookie_cancel -> Cookies 1: ~p", [httpc:which_cookies()]),
-
SetCookieHeaders = [{"set-cookie", "test_cookie=true; path=/;"
"max-age=60000"}],
httpc:store_cookies(SetCookieHeaders, ?URL),
@@ -203,155 +146,60 @@ cookie_cancel(Config) when is_list(Config) ->
NewSetCookieHeaders =
[{"set-cookie", "test_cookie=true; path=/;max-age=0"}],
httpc:store_cookies(NewSetCookieHeaders, ?URL),
- {"cookie", ""} = httpc:cookie_header(?URL),
-
- tsp("cookie_cancel -> Cookies 2: ~p", [httpc:which_cookies()]),
- ok.
+ {"cookie", ""} = httpc:cookie_header(?URL).
-cookie_expires(doc) ->
- ["Test that a cookie is not used when it has expired"];
-cookie_expires(suite) ->
- [];
+cookie_expires() ->
+ [{doc, "Test that a cookie is not used when it has expired"}].
cookie_expires(Config) when is_list(Config) ->
- tsp("cookie_expires -> Cookies 1: ~p", [httpc:which_cookies()]),
-
SetCookieHeaders = [{"set-cookie", "test_cookie=true; path=/;"
"max-age=5"}],
httpc:store_cookies(SetCookieHeaders, ?URL),
{"cookie", "$Version=0; test_cookie=true; $Path=/"} =
httpc:cookie_header(?URL),
- test_server:sleep(10000),
- {"cookie", ""} = httpc:cookie_header(?URL),
-
- tsp("cookie_expires -> Cookies 2: ~p", [httpc:which_cookies()]),
- ok.
+ timer:sleep(10000),
+ {"cookie", ""} = httpc:cookie_header(?URL).
-persistent_cookie(doc) ->
- ["Test domian cookie attribute"];
-persistent_cookie(suite) ->
- [];
+persistent_cookie() ->
+ [{doc, "Test domian cookie attribute"}].
persistent_cookie(Config) when is_list(Config)->
- tsp("persistent_cookie -> Cookies 1: ~p", [httpc:which_cookies()]),
-
SetCookieHeaders = [{"set-cookie", "test_cookie=true; path=/;"
"max-age=60000"}],
httpc:store_cookies(SetCookieHeaders, ?URL),
{"cookie", "$Version=0; test_cookie=true; $Path=/"} =
httpc:cookie_header(?URL),
- CaseDir = ?config(case_top_dir, Config),
+ CaseDir = proplists:get_value(case_top_dir, Config),
application:stop(inets),
application:load(inets),
application:set_env(inets, services, [{httpc, {default, CaseDir}}]),
application:start(inets),
httpc:set_options([{cookies, enabled}]),
- {"cookie","$Version=0; test_cookie=true; $Path=/"} = httpc:cookie_header(?URL),
-
- tsp("persistent_cookie -> Cookies 2: ~p", [httpc:which_cookies()]),
- ok.
+ {"cookie","$Version=0; test_cookie=true; $Path=/"} = httpc:cookie_header(?URL).
-
-domain_cookie(doc) ->
- ["Test the domian cookie attribute"];
-domain_cookie(suite) ->
- [];
+domain_cookie() ->
+ [{doc, "Test the domian cookie attribute"}].
domain_cookie(Config) when is_list(Config) ->
- tsp("domain_cookie -> Cookies 1: ~p", [httpc:which_cookies()]),
-
SetCookieHeaders = [{"set-cookie", "test_cookie=true; path=/;"
"domain=.cookie.test.org"}],
httpc:store_cookies(SetCookieHeaders, ?URL),
{"cookie","$Version=0; test_cookie=true; $Path=/; "
"$Domain=.cookie.test.org"} =
- httpc:cookie_header(?URL_DOMAIN),
+ httpc:cookie_header(?URL_DOMAIN).
- tsp("domain_cookie -> Cookies 2: ~p", [httpc:which_cookies()]),
- ok.
-
-
-secure_cookie(doc) ->
- ["Test the secure cookie attribute"];
-secure_cookie(suite) ->
- [];
+secure_cookie() ->
+ [{doc, "Test the secure cookie attribute"}].
secure_cookie(Config) when is_list(Config) ->
- tsp("secure_cookie -> entry with"
- "~n Config: ~p", [Config]),
-
- %% httpc:reset_cookies(),
-
- tsp("secure_cookie -> Cookies 1: ~p", [httpc:which_cookies()]),
-
SetCookieHeaders = [{"set-cookie", "test_cookie=true; path=/; secure"}],
- tsp("secure_cookie -> store cookies (1)"),
ok = httpc:store_cookies(SetCookieHeaders, ?URL),
-
- tsp("secure_cookie -> Cookies 2: ~p", [httpc:which_cookies()]),
-
- tsp("secure_cookie -> check cookie (secure)"),
check_cookie("$Version=0; test_cookie=true; $Path=/", ?URL_SECURE),
-
- tsp("secure_cookie -> check cookie (plain)"),
check_cookie("", ?URL),
-
- tsp("secure_cookie -> store cookies (2)"),
SetCookieHeaders1 = [{"set-cookie", "test1_cookie=true; path=/; secure"}],
ok = httpc:store_cookies(SetCookieHeaders1, ?URL),
-
- tsp("secure_cookie -> Cookies 3: ~p", [httpc:which_cookies()]),
-
- tsp("secure_cookie -> cookie header (3)"),
check_cookie("$Version=0; test_cookie=true; $Path=/; "
"test1_cookie=true; $Path=/",
- ?URL_SECURE),
-%% {"cookie","$Version=0; test_cookie=true; $Path=/; "
-%% "test1_cookie=true; $Path=/"} = httpc:cookie_header(?URL_SECURE),
-
- tsp("secure_cookie -> Cookies 4: ~p", [httpc:which_cookies()]),
-
- tsp("secure_cookie -> done"),
- ok.
+ ?URL_SECURE).
-expect_cookie_header(No, ExpectedCookie) ->
- case httpc:cookie_header(?URL) of
- {"cookie", ExpectedCookie} ->
- ok;
- {"cookie", BadCookie} ->
- io:format("Bad Cookie ~w: "
- "~n Expected: ~s"
- "~n Received: ~s"
- "~n", [No, ExpectedCookie, BadCookie]),
- exit({bad_cookie_header, No, ExpectedCookie, BadCookie})
- end.
-
-print_cookies(Pre) ->
- io:format("~s: ", [Pre]),
- print_cookies2(httpc:which_cookies()).
-
-print_cookies2([]) ->
- ok;
-print_cookies2([{cookies, Cookies}|Rest]) ->
- print_cookies3("Cookies", Cookies),
- print_cookies2(Rest);
-print_cookies2([{session_cookies, Cookies}|Rest]) ->
- print_cookies3("Session Cookies", Cookies),
- print_cookies2(Rest);
-print_cookies2([_|Rest]) ->
- print_cookies2(Rest).
-
-print_cookies3(Header, []) ->
- io:format(" ~s: []", [Header]);
-print_cookies3(Header, Cookies) ->
- io:format(" ~s: ", [Header]),
- Prefix = " ",
- PrintCookie =
- fun(Cookie) ->
- io:format("~s", [httpc_cookie:image_of(Prefix, Cookie)])
- end,
- lists:foreach(PrintCookie, Cookies).
-
-update_cookie(doc)->
- ["Test that a (plain) cookie can be updated."];
-update_cookie(suite) ->
- [];
+update_cookie()->
+ [{doc, "Test that a (plain) cookie can be updated."}].
update_cookie(Config) when is_list(Config) ->
print_cookies("Cookies before store"),
@@ -376,10 +224,8 @@ update_cookie(Config) when is_list(Config) ->
"test_cookie=false; $Path=/",
expect_cookie_header(2, ExpectCookie2).
-update_cookie_session(doc)->
- ["Test that a session cookie can be updated."];
-update_cookie_session(suite) ->
- [];
+update_cookie_session()->
+ [{doc, "Test that a session cookie can be updated."}].
update_cookie_session(Config) when is_list(Config)->
print_cookies("Cookies before store"),
@@ -399,23 +245,57 @@ update_cookie_session(Config) when is_list(Config)->
expect_cookie_header(2, ExpectedCookie2).
-cookie_attributes(doc) ->
- ["Test attribute not covered by the other test cases"];
-cookie_attributes(suite) ->
- [];
+cookie_attributes() ->
+ [{doc, "Test attribute not covered by the other test cases"}].
cookie_attributes(Config) when is_list(Config) ->
SetCookieHeaders = [{"set-cookie", "test_cookie=true;version=1;"
"comment=foobar; "%% Comment
"foo=bar;" %% Nonsense should be ignored
"max-age=60000"}],
httpc:store_cookies(SetCookieHeaders, ?URL),
- {"cookie","$Version=1; test_cookie=true"} = httpc:cookie_header(?URL),
- ok.
+ {"cookie","$Version=1; test_cookie=true"} = httpc:cookie_header(?URL).
%%--------------------------------------------------------------------
%%% Internal functions
%%--------------------------------------------------------------------
+print_cookies(Pre) ->
+ io:format("~s: ", [Pre]),
+ print_cookies2(httpc:which_cookies()).
+
+print_cookies2([]) ->
+ ok;
+print_cookies2([{cookies, Cookies}|Rest]) ->
+ print_cookies3("Cookies", Cookies),
+ print_cookies2(Rest);
+print_cookies2([{session_cookies, Cookies}|Rest]) ->
+ print_cookies3("Session Cookies", Cookies),
+ print_cookies2(Rest);
+print_cookies2([_|Rest]) ->
+ print_cookies2(Rest).
+
+print_cookies3(Header, []) ->
+ io:format(" ~s: []", [Header]);
+print_cookies3(Header, Cookies) ->
+ io:format(" ~s: ", [Header]),
+ Prefix = " ",
+ PrintCookie =
+ fun(Cookie) ->
+ io:format("~s", [httpc_cookie:image_of(Prefix, Cookie)])
+ end,
+ lists:foreach(PrintCookie, Cookies).
+
+expect_cookie_header(No, ExpectedCookie) ->
+ case httpc:cookie_header(?URL) of
+ {"cookie", ExpectedCookie} ->
+ ok;
+ {"cookie", BadCookie} ->
+ io:format("Bad Cookie ~w: "
+ "~n Expected: ~s"
+ "~n Received: ~s"
+ "~n", [No, ExpectedCookie, BadCookie]),
+ exit({bad_cookie_header, No, ExpectedCookie, BadCookie})
+ end.
check_cookie(Expect, URL) ->
case httpc:cookie_header(URL) of
@@ -425,12 +305,12 @@ check_cookie(Expect, URL) ->
case lists:prefix(Expect, Unexpected) of
true ->
Extra = Unexpected -- Expect,
- tsf({extra_cookie_info, Extra});
+ ct:fail({extra_cookie_info, Extra});
false ->
- tsf({unknown_cookie, Expect, Unexpected})
+ ct:fail({unknown_cookie, Expect, Unexpected})
end;
Bad ->
- tsf({bad_cookies, Bad})
+ ct:fail({bad_cookies, Bad})
end.
@@ -508,11 +388,3 @@ month_str(11) ->"Nov";
month_str(12) ->"Dec".
-tsp(F) ->
- tsp(F, []).
-tsp(F, A) ->
- test_server:format("~p ~p:" ++ F ++ "~n", [self(), ?MODULE | A]).
-
-tsf(Reason) ->
- test_server:fail(Reason).
-
diff --git a/lib/inets/test/httpc_proxy_SUITE.erl b/lib/inets/test/httpc_proxy_SUITE.erl
index 84db39e76b..198b245399 100644
--- a/lib/inets/test/httpc_proxy_SUITE.erl
+++ b/lib/inets/test/httpc_proxy_SUITE.erl
@@ -1,18 +1,19 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2012. All Rights Reserved.
+%% Copyright Ericsson AB 2012-2016. 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.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
+%%
+%% http://www.apache.org/licenses/LICENSE-2.0
+%%
+%% Unless required by applicable law or agreed to in writing, software
+%% distributed under the License is distributed on an "AS IS" BASIS,
+%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+%% See the License for the specific language governing permissions and
+%% limitations under the License.
%%
%% %CopyrightEnd%
%%
@@ -57,7 +58,7 @@ groups() ->
[http_emulate_lower_versions
|local_proxy_cases()]},
{local_proxy_https,[],
- local_proxy_cases()}].
+ local_proxy_cases() ++ local_proxy_https_cases()}].
%% internal functions
@@ -69,16 +70,20 @@ local_proxy_cases() ->
http_post,
http_put,
http_delete,
+ http_delete_body,
http_headers,
http_proxy_auth,
http_doesnotexist,
http_stream,
http_not_modified_otp_6821].
+local_proxy_https_cases() ->
+ [https_connect_error].
+
%%--------------------------------------------------------------------
init_per_suite(Config0) ->
- case init_apps([crypto,public_key], Config0) of
+ case init_apps(suite_apps(), Config0) of
Config when is_list(Config) ->
make_cert_files(dsa, "server-", Config),
Config;
@@ -93,7 +98,7 @@ end_per_suite(_Config) ->
%% internal functions
suite_apps() ->
- [crypto,public_key].
+ [asn1,crypto,public_key].
%%--------------------------------------------------------------------
@@ -136,7 +141,7 @@ end_per_testcase(_Case, Config) ->
%% internal functions
apps(_Case, Config) ->
- case ?config(protocol, Config) of
+ case proplists:get_value(protocol, Config) of
https ->
[ssl];
_ ->
@@ -262,6 +267,22 @@ http_delete(Config) when is_list(Config) ->
%%--------------------------------------------------------------------
+http_delete_body(doc) ->
+ ["Perform a DELETE request with a content body. The server will not allow it "
+ "but we only test sending the request."];
+http_delete_body(Config) when is_list(Config) ->
+ Method = delete,
+ URL = url("/delete.html", Config),
+ Content = "foo=bar",
+ Request = {URL,[],"application/x-www-form-urlencoded",Content},
+ HttpOpts = [],
+ Opts = [],
+ {ok,{{_,405,_},[_|_],[_|_]}} =
+ httpc:request(Method, Request, HttpOpts, Opts),
+ ok.
+
+%%--------------------------------------------------------------------
+
http_headers(doc) ->
["Use as many request headers as possible"];
http_headers(Config) when is_list(Config) ->
@@ -414,6 +435,21 @@ header_value(Name, [{HeaderName,HeaderValue}|Headers]) ->
end.
%%--------------------------------------------------------------------
+https_connect_error(doc) ->
+ ["Error from CONNECT tunnel should be returned"];
+https_connect_error(Config) when is_list(Config) ->
+ {HttpServer,HttpPort} = proplists:get_value(http, Config),
+ Method = get,
+ %% using HTTPS scheme with HTTP port to trigger connection error
+ URL = "https://" ++ HttpServer ++ ":" ++
+ integer_to_list(HttpPort) ++ "/index.html",
+ Opts = [],
+ HttpOpts = [],
+ Request = {URL,[]},
+ {error,{failed_connect,[_,{tls,_,_}]}} =
+ httpc:request(Method, Request, HttpOpts, Opts).
+
+%%--------------------------------------------------------------------
%% Internal Functions ------------------------------------------------
%%--------------------------------------------------------------------
@@ -441,7 +477,7 @@ app_start(App, Config) ->
inets ->
application:stop(App),
ok = application:start(App),
- case ?config(proxy, Config) of
+ case proplists:get_value(proxy, Config) of
undefined -> ok;
{_,ProxySpec} ->
ok = httpc:set_options([{proxy,ProxySpec}])
@@ -459,7 +495,7 @@ app_stop(App) ->
application:stop(App).
make_cert_files(Alg, Prefix, Config) ->
- PrivDir = ?config(priv_dir, Config),
+ PrivDir = proplists:get_value(priv_dir, Config),
CaInfo = {CaCert,_} = erl_make_certs:make_cert([{key,Alg}]),
{Cert,CertKey} = erl_make_certs:make_cert([{key,Alg},{issuer,CaInfo}]),
CaCertFile = filename:join(PrivDir, Prefix++"cacerts.pem"),
@@ -477,8 +513,8 @@ der_to_pem(File, Entries) ->
url(AbsPath, Config) ->
- Protocol = ?config(protocol, Config),
- {ServerName,ServerPort} = ?config(Protocol, Config),
+ Protocol = proplists:get_value(protocol, Config),
+ {ServerName,ServerPort} = proplists:get_value(Protocol, Config),
atom_to_list(Protocol) ++ "://" ++
ServerName ++ ":" ++ integer_to_list(ServerPort) ++
AbsPath.
@@ -512,8 +548,8 @@ init_local_proxy_string(String, Config) ->
|Config].
rcmd_local_proxy(Args, Config) ->
- DataDir = ?config(data_dir, Config),
- PrivDir = ?config(priv_dir, Config),
+ DataDir = proplists:get_value(data_dir, Config),
+ PrivDir = proplists:get_value(priv_dir, Config),
Script = filename:join(DataDir, ?LOCAL_PROXY_SCRIPT),
rcmd(Script, Args, [{cd,PrivDir}]).
diff --git a/lib/inets/test/httpc_proxy_SUITE_data/apache2/apache2.conf b/lib/inets/test/httpc_proxy_SUITE_data/apache2/apache2.conf
index 37af88c510..b139c4ca51 100644
--- a/lib/inets/test/httpc_proxy_SUITE_data/apache2/apache2.conf
+++ b/lib/inets/test/httpc_proxy_SUITE_data/apache2/apache2.conf
@@ -2,18 +2,19 @@
##
## %CopyrightBegin%
##
-## Copyright Ericsson AB 2012. All Rights Reserved.
+## Copyright Ericsson AB 2012-2016. 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/.
+## Licensed under the Apache License, Version 2.0 (the "License");
+## you may not use this file except in compliance with the License.
+## You may obtain a copy of the License at
##
-## 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.
+## http://www.apache.org/licenses/LICENSE-2.0
+##
+## Unless required by applicable law or agreed to in writing, software
+## distributed under the License is distributed on an "AS IS" BASIS,
+## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+## See the License for the specific language governing permissions and
+## limitations under the License.
##
## %CopyrightEnd%
##
diff --git a/lib/inets/test/httpc_proxy_SUITE_data/server_proxy.sh b/lib/inets/test/httpc_proxy_SUITE_data/server_proxy.sh
index 4b05ea63ef..e8b690a4a1 100755
--- a/lib/inets/test/httpc_proxy_SUITE_data/server_proxy.sh
+++ b/lib/inets/test/httpc_proxy_SUITE_data/server_proxy.sh
@@ -5,18 +5,19 @@
##
## %CopyrightBegin%
##
-## Copyright Ericsson AB 2012. All Rights Reserved.
+## Copyright Ericsson AB 2012-2016. 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/.
+## Licensed under the Apache License, Version 2.0 (the "License");
+## you may not use this file except in compliance with the License.
+## You may obtain a copy of the License at
##
-## 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.
+## http://www.apache.org/licenses/LICENSE-2.0
+##
+## Unless required by applicable law or agreed to in writing, software
+## distributed under the License is distributed on an "AS IS" BASIS,
+## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+## See the License for the specific language governing permissions and
+## limitations under the License.
##
## %CopyrightEnd%
##
@@ -168,6 +169,8 @@ MaxRequestsPerChild 0
ViaProxyName "tinyproxy"
ConnectPort $APACHE_HTTPS_PORT
+# to test connect error
+ConnectPort $APACHE_HTTP_PORT
EOF
(tinyproxy -d -c tinyproxy.conf 1>/dev/null 2>&1 </dev/null &)&
wait_for_pidfile tinyproxy.pid
diff --git a/lib/inets/test/httpd_1_0.erl b/lib/inets/test/httpd_1_0.erl
new file mode 100644
index 0000000000..f61dc3c3fd
--- /dev/null
+++ b/lib/inets/test/httpd_1_0.erl
@@ -0,0 +1,39 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2013-2016. All Rights Reserved.
+%%
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
+%%
+%% http://www.apache.org/licenses/LICENSE-2.0
+%%
+%% Unless required by applicable law or agreed to in writing, software
+%% distributed under the License is distributed on an "AS IS" BASIS,
+%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+%% See the License for the specific language governing permissions and
+%% limitations under the License.
+%%
+%% %CopyrightEnd%
+%%
+%%
+
+-module(httpd_1_0).
+
+-export([host/4, trace/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"}]).
+trace(Type, Port, Host, Node)->
+ ok = httpd_test_lib:verify_request(Type, Host, Port, Node,
+ "TRACE / HTTP/1.0\r\n\r\n",
+ [{statuscode, 501},
+ {version, "HTTP/1.0"}]).
diff --git a/lib/inets/test/httpd_1_1.erl b/lib/inets/test/httpd_1_1.erl
index 07d94ea97a..3755ed117b 100644
--- a/lib/inets/test/httpd_1_1.erl
+++ b/lib/inets/test/httpd_1_1.erl
@@ -1,18 +1,19 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2005-2011. All Rights Reserved.
+%% Copyright Ericsson AB 2005-2016. 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.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
+%%
+%% http://www.apache.org/licenses/LICENSE-2.0
+%%
+%% Unless required by applicable law or agreed to in writing, software
+%% distributed under the License is distributed on an "AS IS" BASIS,
+%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+%% See the License for the specific language governing permissions and
+%% limitations under the License.
%%
%% %CopyrightEnd%
%%
@@ -20,12 +21,10 @@
-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,
- head/4, mod_cgi_chunked_encoding_test/5]).
+-export([host/4, chunked/4, expect/4, range/4, if_test/5, trace/4,
+ head/4, mod_cgi_chunked_encoding_test/5, mod_esi_chunk_timeout/4]).
%% -define(all_keys_lower_case,true).
-ifndef(all_keys_lower_case).
@@ -40,14 +39,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",
@@ -158,13 +153,13 @@ if_test(Type, Port, Host, Node, DocRoot)->
calendar:datetime_to_gregorian_seconds(FileInfo#file_info.mtime),
Mod = httpd_util:rfc1123_date(calendar:gregorian_seconds_to_datetime(
- CreatedSec-1)),
+ CreatedSec-1)),
%% Test that we get the data when the file is modified
ok = httpd_test_lib:verify_request(Type, Host, Port, Node,
"GET / HTTP/1.1\r\nHost:" ++ Host ++
- "\r\nIf-Modified-Since:" ++
- Mod ++ "\r\n\r\n",
+ "\r\nIf-Modified-Since:" ++
+ Mod ++ "\r\n\r\n",
[{statuscode, 200}]),
Mod1 = httpd_util:rfc1123_date(calendar:gregorian_seconds_to_datetime(
CreatedSec+100)),
@@ -174,83 +169,70 @@ if_test(Type, Port, Host, Node, DocRoot)->
++ Mod1 ++"\r\n\r\n",
[{statuscode, 304}]),
-
+
ok = httpd_test_lib:verify_request(Type, Host, Port, Node,
"GET / HTTP/1.1\r\nHost:" ++ Host ++
- "\r\nIf-Modified-Since:" ++
- "AAA[...]AAAA" ++ "\r\n\r\n",
+ "\r\nIf-Modified-Since:" ++
+ "AAA[...]AAAA" ++ "\r\n\r\n",
[{statuscode, 400}]),
-
-
- Mod2 = httpd_util:rfc1123_date(calendar:gregorian_seconds_to_datetime(
+
+ Mod2 = httpd_util:rfc1123_date(calendar:gregorian_seconds_to_datetime(
CreatedSec+1)),
- %% Control that the If-Unmodified-Header lmits the response
- ok = httpd_test_lib:verify_request(Type,Host,Port,Node,
- "GET / HTTP/1.1\r\nHost:"
- ++ Host ++
- "\r\nIf-Unmodified-Since:" ++ Mod2
- ++ "\r\n\r\n",
- [{statuscode, 200}]),
- Mod3 = httpd_util:rfc1123_date(calendar:gregorian_seconds_to_datetime(
+ %% Control that the If-Unmodified-Header lmits the response
+ ok = httpd_test_lib:verify_request(Type,Host,Port,Node,
+ "GET / HTTP/1.1\r\nHost:"
+ ++ Host ++
+ "\r\nIf-Unmodified-Since:" ++ Mod2
+ ++ "\r\n\r\n",
+ [{statuscode, 200}]),
+ Mod3 = httpd_util:rfc1123_date(calendar:gregorian_seconds_to_datetime(
CreatedSec-1)),
ok = httpd_test_lib:verify_request(Type, Host, Port, Node,
- "GET / HTTP/1.1\r\nHost:"
- ++ Host ++
- "\r\nIf-Unmodified-Since:"++ Mod3
+ "GET / HTTP/1.1\r\nHost:"
+ ++ Host ++
+ "\r\nIf-Unmodified-Since:"++ Mod3
++"\r\n\r\n",
- [{statuscode, 412}]),
+ [{statuscode, 412}]),
- %% Control that we get the body when the etag match
- ok = httpd_test_lib:verify_request(Type, Host, Port, Node,
- "GET / HTTP/1.1\r\nHost:" ++ Host
- ++"\r\n"++
- "If-Match:"++
- httpd_util:create_etag(FileInfo)++
- "\r\n\r\n",
- [{statuscode, 200}]),
+ %% Control that we get the body when the etag match
ok = httpd_test_lib:verify_request(Type, Host, Port, Node,
- "GET / HTTP/1.1\r\nHost:" ++
- Host ++ "\r\n"++
- "If-Match:NotEtag\r\n\r\n",
- [{statuscode, 412}]),
+ "GET / HTTP/1.1\r\nHost:" ++ Host
+ ++"\r\n"++
+ "If-Match:"++
+ httpd_util:create_etag(FileInfo)++
+ "\r\n\r\n",
+ [{statuscode, 200}]),
+ ok = httpd_test_lib:verify_request(Type, Host, Port, Node,
+ "GET / HTTP/1.1\r\nHost:" ++
+ Host ++ "\r\n"++
+ "If-Match:NotEtag\r\n\r\n",
+ [{statuscode, 412}]),
- %% Control the response when the if-none-match header is there
- ok = httpd_test_lib:verify_request(Type, Host, Port, Node,
- "GET / HTTP/1.1\r\nHost:"
- ++ Host ++"\r\n"++
- "If-None-Match:NoTaag," ++
- httpd_util:create_etag(FileInfo) ++
- "\r\n\r\n",
- [{statuscode, 304}]),
+ %% Control the response when the if-none-match header is there
+ ok = httpd_test_lib:verify_request(Type, Host, Port, Node,
+ "GET / HTTP/1.1\r\nHost:"
+ ++ Host ++"\r\n"++
+ "If-None-Match:NoTaag," ++
+ httpd_util:create_etag(FileInfo) ++
+ "\r\n\r\n",
+ [{statuscode, 304}]),
ok = httpd_test_lib:verify_request(Type, Host, Port, Node,
"GET / HTTP/1.1\r\nHost:"
- ++ Host ++ "\r\n"++
- "If-None-Match:NotEtag,"
- "NeihterEtag\r\n\r\n",
+ ++ Host ++ "\r\n"++
+ "If-None-Match:NotEtag,"
+ "NeihterEtag\r\n\r\n",
[{statuscode,200}]),
ok.
-
-http_trace(Type, Port, Host, Node)->
+
+trace(Type, Port, Host, Node)->
ok = httpd_test_lib:verify_request(Type, Host, Port, Node,
"TRACE / HTTP/1.1\r\n" ++
"Host:" ++ Host ++ "\r\n" ++
"Max-Forwards:2\r\n\r\n",
- [{statuscode, 200}]),
- ok = httpd_test_lib:verify_request(Type, Host, Port, Node,
- "TRACE / HTTP/1.0\r\n\r\n",
- [{statuscode, 501},
- {version, "HTTP/1.0"}]).
+ [{statuscode, 200}]).
head(Type, Port, Host, Node)->
- %% mod_include
- ok = httpd_test_lib:verify_request(Type, Host, Port, Node,
- "HEAD /fsize.shtml HTTP/1.0\r\n\r\n",
- [{statuscode, 200},
- {version, "HTTP/1.0"}]),
- ok = httpd_test_lib:verify_request(Type, Host, Port, Node,
- "HEAD /fsize.shtml HTTP/1.1\r\nhost:" ++
- Host ++ "\r\n\r\n", [{statuscode, 200}]),
%% mod_esi
ok = httpd_test_lib:verify_request(Type, Host, Port, Node,
"HEAD /cgi-bin/erl/httpd_example/newformat"
@@ -284,12 +266,21 @@ mod_cgi_chunked_encoding_test(Type, Port, Host, Node, [Request| Rest])->
[{statuscode, 200}]),
mod_cgi_chunked_encoding_test(Type, Port, Host, Node, Rest).
+
+mod_esi_chunk_timeout(Type, Port, Host, Node) ->
+ ok = httpd_test_lib:verify_request(Type, Host, Port, Node,
+ "GET /cgi-bin/erl/httpd_example/chunk_timeout?input=20000 HTTP/1.1\r\n"
+ "Host:"++ Host ++"\r\n"
+ "\r\n",
+ [{statuscode, 200},
+ {header, "warning"}]).
+
%%--------------------------------------------------------------------
%% Internal functions
%%--------------------------------------------------------------------
validateRangeRequest(Socket,Response,ValidBody,C,O,DE)->
receive
- {tcp,Socket,Data} ->
+ {_,Socket,Data} ->
case string:str(Data,"\r\n") of
0->
validateRangeRequest(Socket,
@@ -318,7 +309,7 @@ validateRangeRequest1(Socket, Response, ValidBody) ->
case end_of_header(Response) of
false ->
receive
- {tcp,Socket,Data} ->
+ {_,Socket,Data} ->
validateRangeRequest1(Socket, Response ++ Data,
ValidBody);
_->
@@ -337,10 +328,10 @@ validateRangeRequest2(Socket, Head, Body, ValidBody, {multiPart,Boundary})->
validateMultiPartRangeRequest(Body, ValidBody, Boundary);
false->
receive
- {tcp, Socket, Data} ->
+ {_, Socket, Data} ->
validateRangeRequest2(Socket, Head, Body ++ Data,
ValidBody, {multiPart, Boundary});
- {tcp_closed, Socket} ->
+ {_, Socket} ->
error;
_ ->
error
@@ -359,7 +350,7 @@ validateRangeRequest2(Socket, Head, Body, ValidBody, BodySize)
end;
Size when Size < BodySize ->
receive
- {tcp, Socket, Data} ->
+ {_, Socket, Data} ->
validateRangeRequest2(Socket, Head,
Body ++ Data, ValidBody, BodySize);
_ ->
@@ -371,18 +362,18 @@ validateRangeRequest2(Socket, Head, Body, ValidBody, BodySize)
validateMultiPartRangeRequest(Body, ValidBody, Boundary)->
- case inets_regexp:split(Body,"--"++Boundary++"--") of
+ case re:split(Body,"--"++Boundary++"--", [{return, list}]) of
%%Last is the epilogue and must be ignored
- {ok,[First | _Last]}->
+ [First | _Last]->
%%First is now the actuall http request body.
- case inets_regexp:split(First, "--" ++ Boundary) of
+ case re:split(First, "--" ++ Boundary, [{return, list}]) of
%%Parts is now a list of ranges and the heads for each range
%%Gues we try to split out the body
- {ok,Parts}->
+ Parts->
case lists:flatten(lists:map(fun splitRange/1,Parts)) of
ValidBody->
ok;
- ParsedBody->
+ ParsedBody->
error = ParsedBody
end
end;
@@ -392,8 +383,8 @@ validateMultiPartRangeRequest(Body, ValidBody, Boundary)->
splitRange(Part)->
- case inets_regexp:split(Part, "\r\n\r\n") of
- {ok,[_, Body]} ->
+ case re:split(Part, "\r\n\r\n", [{return, list}]) of
+ [_, Body] ->
string:substr(Body, 1, length(Body) - 2);
_ ->
[]
@@ -413,13 +404,13 @@ getRangeSize(Head)->
{multiPart, BoundaryString}->
{multiPart, BoundaryString};
_X1 ->
- case inets_regexp:match(Head, ?CONTENT_RANGE "bytes=.*\r\n") of
- {match, Start, Lenght} ->
+ case re:run(Head, ?CONTENT_RANGE "bytes=.*\r\n", [{capture, first}]) of
+ {match, [{Start, Lenght}]} ->
%% Get the range data remove the fieldname and the
%% end of line.
- RangeInfo = string:substr(Head, Start + 20,
- Lenght - (20 - 2)),
- rangeSize(RangeInfo);
+ RangeInfo = string:substr(Head, Start + 1 + 20,
+ Lenght - (20 +2)),
+ rangeSize(string:strip(RangeInfo));
_X2 ->
error
end
@@ -455,10 +446,10 @@ num(_CharVal, false) ->
true.
controlMimeType(Head)->
- case inets_regexp:match(Head,?CONTENT_TYPE "multipart/byteranges.*\r\n") of
- {match,Start,Length}->
+ case re:run(Head,?CONTENT_TYPE "multipart/byteranges.*\r\n", [{capture, first}]) of
+ {match, [{Start,Length}]}->
FieldNameLen = length(?CONTENT_TYPE "multipart/byteranges"),
- case clearBoundary(string:substr(Head, Start + FieldNameLen,
+ case clearBoundary(string:substr(Head, Start + 1 + FieldNameLen,
Length - (FieldNameLen+2))) of
error ->
error;
@@ -472,10 +463,10 @@ controlMimeType(Head)->
end.
clearBoundary(Boundary)->
- case inets_regexp:match(Boundary, "boundary=.*\$") of
- {match, Start1, Length1}->
+ case re:run(Boundary, "boundary=.*\$", [{capture, first}]) of
+ {match, [{Start1, Length1}]}->
BoundLen = length("boundary="),
- string:substr(Boundary, Start1 + BoundLen, Length1 - BoundLen);
+ string:substr(Boundary, Start1 + 1 + BoundLen, Length1 - BoundLen);
_ ->
error
end.
@@ -490,12 +481,12 @@ end_of_header(HeaderPart) ->
end.
get_body_size(Head) ->
- case inets_regexp:match(Head,?CONTENT_LENGTH ".*\r\n") of
- {match, Start, Length} ->
+ case re:run(Head,?CONTENT_LENGTH ".*\r\n", [{capture, first}]) of
+ {match, [{Start, Length}]} ->
%% 15 is length of Content-Length,
%% 17 Is length of Content-Length and \r\
S = list_to_integer(
- string:strip(string:substr(Head, Start + 15, Length-17))),
+ string:strip(string:substr(Head, Start +1 + 15, Length-17))),
S;
_->
0
diff --git a/lib/inets/test/httpd_SUITE.erl b/lib/inets/test/httpd_SUITE.erl
index 1efa78a63e..3194b5ad3d 100644
--- a/lib/inets/test/httpd_SUITE.erl
+++ b/lib/inets/test/httpd_SUITE.erl
@@ -1,2229 +1,1865 @@
%%
%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2013-2015. All Rights Reserved.
+%%
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% 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.
+%% http://www.apache.org/licenses/LICENSE-2.0
%%
+%% Unless required by applicable law or agreed to in writing, software
+%% distributed under the License is distributed on an "AS IS" BASIS,
+%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+%% See the License for the specific language governing permissions and
+%% limitations under the License.
+%%
%% %CopyrightEnd%
%%
%%
+%%
+%% ct:run("../inets_test", httpd_SUITE).
+%%
+
-module(httpd_SUITE).
--include_lib("test_server/include/test_server.hrl").
--include("test_server_line.hrl").
+-include_lib("kernel/include/file.hrl").
+-include_lib("common_test/include/ct.hrl").
+-include_lib("public_key/include/public_key.hrl").
-include("inets_test_lib.hrl").
--include_lib("kernel/include/file.hrl").
+%% Note: This directive should only be used in test suites.
+-compile(export_all).
-%% 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).
+-record(httpd_user, {user_name, password, user_data}).
+-record(httpd_group, {group_name, userlist}).
-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}).
-
+-define(URL_START, "http://").
%%--------------------------------------------------------------------
-%% 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]},
+ {timetrap,{seconds, 120}}
+ ].
-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_basic},
+ {group, https_basic},
+ {group, http_limit},
+ {group, https_limit},
+ {group, http_custom},
+ {group, https_custom},
+ {group, http_basic_auth},
+ {group, https_basic_auth},
+ {group, http_auth_api},
+ {group, https_auth_api},
+ {group, http_auth_api_dets},
+ {group, https_auth_api_dets},
+ {group, http_auth_api_mnesia},
+ {group, https_auth_api_mnesia},
+ {group, http_htaccess},
+ {group, https_htaccess},
+ {group, http_security},
+ {group, https_security},
+ {group, http_reload},
+ {group, https_reload},
+ {group, http_mime_types},
+ mime_types_format
].
-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(_GroupName, Config) ->
- Config.
+ {http_basic, [], basic_groups()},
+ {https_basic, [], basic_groups()},
+ {http_limit, [], [{group, limit}]},
+ {https_limit, [], [{group, limit}]},
+ {http_custom, [], [{group, custom}]},
+ {https_custom, [], [{group, custom}]},
+ {http_basic_auth, [], [{group, basic_auth}]},
+ {https_basic_auth, [], [{group, basic_auth}]},
+ {http_auth_api, [], [{group, auth_api}]},
+ {https_auth_api, [], [{group, auth_api}]},
+ {http_auth_api_dets, [], [{group, auth_api_dets}]},
+ {https_auth_api_dets, [], [{group, auth_api_dets}]},
+ {http_auth_api_mnesia, [], [{group, auth_api_mnesia}]},
+ {https_auth_api_mnesia, [], [{group, auth_api_mnesia}]},
+ {http_htaccess, [], [{group, htaccess}]},
+ {https_htaccess, [], [{group, htaccess}]},
+ {http_security, [], [{group, security}]},
+ {https_security, [], [{group, security}]},
+ {http_reload, [], [{group, reload}]},
+ {https_reload, [], [{group, reload}]},
+ {http_mime_types, [], [alias_1_1, alias_1_0, alias_0_9]},
+ {limit, [], [max_clients_1_1, max_clients_1_0, max_clients_0_9]},
+ {custom, [], [customize, add_default]},
+ {reload, [], [non_disturbing_reconfiger_dies,
+ disturbing_reconfiger_dies,
+ non_disturbing_1_1,
+ non_disturbing_1_0,
+ non_disturbing_0_9,
+ disturbing_1_1,
+ disturbing_1_0,
+ disturbing_0_9
+ ]},
+ {basic_auth, [], [basic_auth_1_1, basic_auth_1_0, basic_auth_0_9]},
+ {auth_api, [], [auth_api_1_1, auth_api_1_0, auth_api_0_9
+ ]},
+ {auth_api_dets, [], [auth_api_1_1, auth_api_1_0, auth_api_0_9
+ ]},
+ {auth_api_mnesia, [], [auth_api_1_1, auth_api_1_0, auth_api_0_9
+ ]},
+ {htaccess, [], [htaccess_1_1, htaccess_1_0, htaccess_0_9]},
+ {security, [], [security_1_1, security_1_0]}, %% Skip 0.9 as causes timing issus in test code
+ {http_1_1, [], [host, chunked, expect, cgi, cgi_chunked_encoding_test,
+ trace, range, if_modified_since, mod_esi_chunk_timeout] ++ http_head() ++ http_get() ++ load()},
+ {http_1_0, [], [host, cgi, trace] ++ http_head() ++ http_get() ++ load()},
+ {http_0_9, [], http_head() ++ http_get() ++ load()}
+ ].
-end_per_group(_GroupName, Config) ->
- Config.
+basic_groups ()->
+ [{group, http_1_1},
+ {group, http_1_0},
+ {group, http_0_9}
+ ].
+http_head() ->
+ [head].
+http_get() ->
+ [alias,
+ get,
+ %%actions, Add configuration so that this test mod_action
+ esi,
+ content_length,
+ bad_hex,
+ missing_CR,
+ max_header,
+ max_content_length,
+ ipv6
+ ].
-%%--------------------------------------------------------------------
-%% 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.
-%%--------------------------------------------------------------------
+load() ->
+ [light, medium
+ %%,heavy
+ ].
+
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},
+ PrivDir = proplists:get_value(priv_dir, Config),
+ DataDir = proplists:get_value(data_dir, Config),
+ inets_test_lib:stop_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),
+ {ok, Hostname0} = inet:gethostname(),
+ Inet =
+ case (catch ct:get_config(ipv6_hosts)) of
+ undefined ->
+ inet;
+ Hosts when is_list(Hosts) ->
+ case lists:member(list_to_atom(Hostname0), Hosts) of
+ true ->
+ inet6;
+ false ->
+ inet
+ end;
+ _ ->
+ inet
+ end,
+ [{server_root, ServerRoot},
+ {doc_root, DocRoot},
+ {ipfamily, Inet},
{node, node()},
- {host, inets_test_lib:hostname()},
+ {host, inets_test_lib:hostname()},
{address, getaddr()} | Config].
+end_per_suite(_Config) ->
+ ok.
%%--------------------------------------------------------------------
-%% Function: end_per_suite(Config) -> _
-%% Config - [tuple()]
-%% A list of key/value pairs, holding the test case configuration.
-%% Description: Cleanup after the whole suite
-%%--------------------------------------------------------------------
+init_per_group(Group, Config0) when Group == https_basic;
+ Group == https_limit;
+ Group == https_custom;
+ Group == https_basic_auth;
+ Group == https_auth_api;
+ Group == https_auth_api_dets;
+ Group == https_auth_api_mnesia;
+ Group == https_security;
+ Group == https_reload
+ ->
+ init_ssl(Group, Config0);
+init_per_group(Group, Config0) when Group == http_basic;
+ Group == http_limit;
+ Group == http_custom;
+ Group == http_basic_auth;
+ Group == http_auth_api;
+ Group == http_auth_api_dets;
+ Group == http_auth_api_mnesia;
+ Group == http_security;
+ Group == http_reload;
+ Group == http_mime_types
+ ->
+ ok = start_apps(Group),
+ 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) ->
+ case {os:type(), os:version()} of
+ {{win32, _}, {5,1,2600}} ->
+ {skip, "eaddrinuse XP problem"};
+ _ ->
+ [{http_version, "HTTP/0.9"} | Config]
+ end;
+init_per_group(http_htaccess = Group, Config) ->
+ Path = proplists:get_value(doc_root, Config),
+ catch remove_htaccess(Path),
+ create_htaccess_data(Path, proplists:get_value(address, Config)),
+ ok = start_apps(Group),
+ init_httpd(Group, [{type, ip_comm} | Config]);
+init_per_group(https_htaccess = Group, Config) ->
+ Path = proplists:get_value(doc_root, Config),
+ catch remove_htaccess(Path),
+ create_htaccess_data(Path, proplists:get_value(address, Config)),
+ init_ssl(Group, Config);
+init_per_group(auth_api, Config) ->
+ [{auth_prefix, ""} | Config];
+init_per_group(auth_api_dets, Config) ->
+ [{auth_prefix, "dets_"} | Config];
+init_per_group(auth_api_mnesia, Config) ->
+ start_mnesia(proplists:get_value(node, Config)),
+ [{auth_prefix, "mnesia_"} | Config];
+init_per_group(_, Config) ->
+ Config.
-end_per_suite(_Config) ->
- %% SuiteTopDir = ?config(suite_top_dir, Config),
- %% inets_test_lib:del_dirs(SuiteTopDir),
+end_per_group(Group, _Config) when Group == http_basic;
+ Group == http_limit;
+ Group == http_basic_auth;
+ Group == http_auth_api;
+ Group == http_auth_api_dets;
+ Group == http_auth_api_mnesia;
+ Group == http_htaccess;
+ Group == http_security;
+ Group == http_reload;
+ Group == http_mime_types
+ ->
+ inets:stop();
+end_per_group(Group, _Config) when Group == https_basic;
+ Group == https_limit;
+ Group == https_basic_auth;
+ Group == https_auth_api;
+ Group == https_auth_api_dets;
+ Group == https_auth_api_mnesia;
+ Group == https_htaccess;
+ Group == https_security;
+ Group == https_reload
+ ->
+ ssl:stop(),
+ inets:stop();
+
+end_per_group(auth_api_mnesia, _) ->
+ cleanup_mnesia();
+
+end_per_group(_, _) ->
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_testcase(Case, Config) when Case == host; Case == trace ->
+ ct:timetrap({seconds, 20}),
+ Prop = proplists:get_value(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,
+ [{version_cb, Cb} | proplists:delete(version_cb, Config)];
+
+init_per_testcase(range, Config) ->
+ ct:timetrap({seconds, 20}),
+ DocRoot = proplists:get_value(doc_root, Config),
+ create_range_data(DocRoot),
+ Config;
+
+init_per_testcase(_, Config) ->
+ ct:timetrap({seconds, 20}),
+ Config.
+end_per_testcase(_Case, _Config) ->
+ ok.
-init_per_testcase2(Case, Config) ->
+%%-------------------------------------------------------------------------
+%% Test cases starts here.
+%%-------------------------------------------------------------------------
- %% tsp("init_per_testcase2 -> entry with"
- %% "~n Config: ~p", [Config]),
+head() ->
+ [{doc, "HTTP HEAD request for static page"}].
+
+head(Config) when is_list(Config) ->
+ Version = proplists:get_value(http_version, Config),
+ Host = proplists:get_value(host, Config),
+ ok = httpd_test_lib:verify_request(proplists:get_value(type, Config), Host,
+ proplists:get_value(port, Config), proplists:get_value(node, Config),
+ http_request("HEAD /index.html ", Version, Host),
+ [{statuscode, head_status(Version)},
+ {version, Version}]).
+
+get() ->
+ [{doc, "HTTP GET request for static page"}].
+
+get(Config) when is_list(Config) ->
+ Version = proplists:get_value(http_version, Config),
+ Host = proplists:get_value(host, Config),
+ Type = proplists:get_value(type, Config),
+ ok = httpd_test_lib:verify_request(proplists:get_value(type, Config), Host,
+ proplists:get_value(port, Config),
+ transport_opts(Type, Config),
+ proplists:get_value(node, Config),
+ http_request("GET /index.html ", Version, Host),
+ [{statuscode, 200},
+ {header, "Content-Type", "text/html"},
+ {header, "Date"},
+ {header, "Server"},
+ {version, Version}]).
+
+basic_auth_1_1(Config) when is_list(Config) ->
+ basic_auth([{http_version, "HTTP/1.1"} | Config]).
+
+basic_auth_1_0(Config) when is_list(Config) ->
+ basic_auth([{http_version, "HTTP/1.0"} | Config]).
+
+basic_auth_0_9(Config) when is_list(Config) ->
+ basic_auth([{http_version, "HTTP/0.9"} | Config]).
+
+basic_auth() ->
+ [{doc, "Test Basic authentication with WWW-Authenticate header"}].
+
+basic_auth(Config) ->
+ Version = proplists:get_value(http_version, Config),
+ Host = proplists:get_value(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).
+
+auth_api_1_1(Config) when is_list(Config) ->
+ auth_api([{http_version, "HTTP/1.1"} | Config]).
+
+auth_api_1_0(Config) when is_list(Config) ->
+ auth_api([{http_version, "HTTP/1.0"} | Config]).
+
+auth_api_0_9(Config) when is_list(Config) ->
+ auth_api([{http_version, "HTTP/0.9"} | Config]).
+
+auth_api() ->
+ [{doc, "Test mod_auth API"}].
+
+auth_api(Config) when is_list(Config) ->
+ Prefix = proplists:get_value(auth_prefix, Config),
+ do_auth_api(Prefix, Config).
+
+do_auth_api(AuthPrefix, Config) ->
+ Version = proplists:get_value(http_version, Config),
+ Host = proplists:get_value(host, Config),
+ Port = proplists:get_value(port, Config),
+ Node = proplists:get_value(node, Config),
+ ServerRoot = proplists:get_value(server_root, 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("/" ++ AuthPrefix ++ "open/",
+ "dummy", "WrongPassword", Version, Host), Config,
+ [{statuscode, 401},
+ {header, "WWW-Authenticate"}]),
+ ok = auth_status(auth_request("/" ++ AuthPrefix ++ "open/", "dummy", "WrongPassword",
+ Version, Host), Config, [{statuscode, 401},
+ {header, "WWW-Authenticate"}]),
- 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]),
+ %% 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, AuthPrefix,
+ "open", "NoPassword", "DummyPassword"),
+ {error,bad_password} =
+ add_user(Node, ServerRoot, Port, AuthPrefix, "open", "one",
+ "onePassword", []),
+ ok = update_password(Node, ServerRoot, Host, Port, AuthPrefix, "open",
+ "DummyPassword", "NoPassword"),
+
+ %% Test /*open, require user one Aladdin
+ remove_users(Node, ServerRoot, Host, Port, AuthPrefix, "open"),
- 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"]),
+ ok = auth_status(auth_request("/" ++ AuthPrefix ++ "open/",
+ "one", "onePassword", Version, Host), Config,
+ [{statuscode, 401}]),
- %% 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}),
+ ok = auth_status(auth_request("/" ++ AuthPrefix ++ "open/",
+ "two", "twoPassword", Version, Host), Config,
+ [{statuscode, 401}]),
+
+ ok = auth_status(auth_request("/" ++ AuthPrefix ++ "open/",
+ "Aladdin", "onePassword", Version, Host),
+ Config, [{statuscode, 401}]),
- 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}),
+ true = add_user(Node, ServerRoot, Port, AuthPrefix, "open", "one",
+ "onePassword", []),
+ true = add_user(Node, ServerRoot, Port, AuthPrefix, "open", "two",
+ "twoPassword", []),
+ true = add_user(Node, ServerRoot, Port, AuthPrefix, "open", "Aladdin",
+ "AladdinPassword", []),
+ {ok, [_|_]} = list_users(Node, ServerRoot, Host, Port,
+ AuthPrefix, "open"),
+ ok = auth_status(auth_request("/" ++ AuthPrefix ++ "open/",
+ "one", "WrongPassword", Version, Host),
+ Config, [{statuscode, 401}]),
+ ok = auth_status(auth_request("/" ++ AuthPrefix ++ "open/",
+ "one", "onePassword", Version, Host),
+ Config, [{statuscode, 200}]),
+ ok = auth_status(auth_request("/" ++ AuthPrefix ++ "open/",
+ "two", "twoPassword", Version, Host),
+ Config,[{statuscode, 401}]),
+ ok = auth_status(auth_request("/" ++ AuthPrefix ++ "open/",
+ "Aladdin", "WrongPassword", Version, Host),
+ Config,[{statuscode, 401}]),
+ ok = auth_status(auth_request("/" ++ AuthPrefix ++ "open/",
+ "Aladdin", "AladdinPassword", Version, Host),
+ Config, [{statuscode, 200}]),
- %% 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]),
-
+ remove_users(Node, ServerRoot, Host, Port, AuthPrefix, "open"),
+ {ok, []} = list_users(Node, ServerRoot, Host, Port,
+ AuthPrefix, "open"),
-%% %% Create a new fresh node to be used by the server in this test-case
+ %% Phase 2
+ remove_users(Node, ServerRoot, Host, Port, AuthPrefix, "secret"),
+ {ok, []} = list_users(Node, ServerRoot, Host, Port, AuthPrefix,
+ "secret"),
+ ok = auth_status(auth_request("/" ++ AuthPrefix ++ "secret/",
+ "one", "onePassword", Version, Host),
+ Config, [{statuscode, 401}]),
+ ok = auth_status(auth_request("/" ++ AuthPrefix ++ "secret/",
+ "two", "twoPassword", Version, Host),
+ Config, [{statuscode, 401}]),
+ ok = auth_status(auth_request("/" ++ AuthPrefix ++ "secret/",
+ "three", "threePassword", Version, Host),
+ Config, [{statuscode, 401}]),
+ add_user(Node, ServerRoot, Port, AuthPrefix, "secret", "one",
+ "onePassword",
+ []),
+ add_user(Node, ServerRoot, Port, AuthPrefix, "secret",
+ "two", "twoPassword", []),
+ add_user(Node, ServerRoot, Port, AuthPrefix, "secret", "Aladdin",
+ "AladdinPassword",[]),
+ add_group_member(Node, ServerRoot, Port, AuthPrefix, "secret",
+ "one", "group1"),
+ add_group_member(Node, ServerRoot, Port, AuthPrefix, "secret",
+ "two", "group1"),
+ add_group_member(Node, ServerRoot, Port, AuthPrefix,
+ "secret", "Aladdin", "group2"),
+ ok = auth_status(auth_request("/" ++ AuthPrefix ++ "secret/",
+ "one", "onePassword", Version, Host),
+ Config, [{statuscode, 200}]),
+ ok = auth_status(auth_request("/" ++ AuthPrefix ++ "secret/",
+ "two", "twoPassword", Version, Host),
+ Config,[{statuscode, 200}]),
+ ok = auth_status(auth_request("/" ++ AuthPrefix ++ "secret/",
+ "Aladdin", "AladdinPassword", Version, Host),
+ Config, [{statuscode, 200}]),
+ ok = auth_status(auth_request("/" ++ AuthPrefix ++ "secret/",
+ "three", "threePassword", Version, Host),
+ Config, [{statuscode, 401}]),
+ remove_users(Node, ServerRoot, Host, Port, AuthPrefix, "secret"),
+ {ok, []} = list_users(Node, ServerRoot, Host, Port,
+ AuthPrefix, "secret"),
+ remove_groups(Node, ServerRoot, Host, Port, AuthPrefix, "secret"),
-%% NodeName = list_to_atom(atom_to_list(Case) ++ "_httpd"),
-%% Node = inets_test_lib:start_node(NodeName),
+ {ok, []} = list_groups(Node, ServerRoot, Host, Port, AuthPrefix, "secret"),
- %% 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,
+ %% Phase 3
+ remove_users(Node, ServerRoot, Host, Port, AuthPrefix, "secret/top_secret"),
+ remove_groups(Node, ServerRoot, Host, Port, AuthPrefix, "secret/top_secret"),
- 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 = auth_status(auth_request("/" ++ AuthPrefix ++
+ "secret/top_secret/",
+ "three", "threePassword", Version, Host),
+ Config, [{statuscode, 401}]),
+ ok = auth_status(auth_request("/" ++ AuthPrefix ++
+ "secret/top_secret/", "two", "twoPassword", Version, Host),
+ Config, [{statuscode, 401}]),
+ add_user(Node, ServerRoot, Port, AuthPrefix,
+ "secret/top_secret","three",
+ "threePassword",[]),
+ add_user(Node, ServerRoot, Port, AuthPrefix, "secret/top_secret",
+ "two","twoPassword", []),
+ add_group_member(Node, ServerRoot, Port, AuthPrefix, "secret/top_secret", "three", "group3"),
+ ok = auth_status(auth_request("/" ++ AuthPrefix ++
+ "secret/top_secret/", "three", "threePassword",
+ Version, Host),
+ Config, [{statuscode, 200}]),
+ ok = auth_status(auth_request("/" ++ AuthPrefix ++
+ "secret/top_secret/", "two", "twoPassword", Version, Host),
+ Config, [{statuscode, 401}]),
+ add_group_member(Node, ServerRoot, Port, AuthPrefix, "secret/top_secret", "two", "group3"),
+ ok = auth_status(auth_request("/" ++ AuthPrefix ++
+ "secret/top_secret/",
+ "two", "twoPassword", Version, Host),
+ Config, [{statuscode, 200}]),
+ remove_users(Node, ServerRoot, Host, Port, AuthPrefix, "secret/top_secret"),
+ {ok, []} = list_users(Node, ServerRoot, Host, Port,
+ AuthPrefix, "secret/top_secret"),
+ remove_groups(Node, ServerRoot, Host, Port, AuthPrefix, "secret/top_secret"),
+ {ok, []} = list_groups(Node, ServerRoot, Host, Port, AuthPrefix, "secret/top_secret"),
+ ok = auth_status(auth_request("/" ++ AuthPrefix ++
+ "secret/top_secret/", "two", "twoPassword", Version, Host),
+ Config, [{statuscode, 401}]),
+ ok = auth_status(auth_request("/" ++ AuthPrefix ++
+ "secret/top_secret/","three", "threePassword", Version, Host),
+ Config, [{statuscde, 401}]).
+%%-------------------------------------------------------------------------
+ipv6() ->
+ [{require, ipv6_hosts},
+ {doc,"Test ipv6."}].
+ipv6(Config) when is_list(Config) ->
+ {ok, Hostname0} = inet:gethostname(),
+ case lists:member(list_to_atom(Hostname0), ct:get_config(ipv6_hosts)) of
+ true ->
+ Version = proplists:get_value(http_version, Config),
+ Host = proplists:get_value(host, Config),
+ URI = http_request("GET / ", Version, Host),
+ httpd_test_lib:verify_request(proplists:get_value(type, Config), Host,
+ proplists:get_value(port, Config), [inet6],
+ proplists:get_value(code, Config),
+ URI,
+ [{statuscode, 200}, {version, Version}]);
+ false ->
+ {skip, "Host does not support IPv6"}
+ end.
+
+%%-------------------------------------------------------------------------
+htaccess_1_1(Config) when is_list(Config) ->
+ htaccess([{http_version, "HTTP/1.1"} | Config]).
+
+htaccess_1_0(Config) when is_list(Config) ->
+ htaccess([{http_version, "HTTP/1.0"} | Config]).
+
+htaccess_0_9(Config) when is_list(Config) ->
+ htaccess([{http_version, "HTTP/0.9"} | Config]).
+
+htaccess() ->
+ [{doc, "Test mod_auth API"}].
+
+htaccess(Config) when is_list(Config) ->
+ Version = proplists:get_value(http_version, Config),
+ Host = proplists:get_value(host, Config),
+ Type = proplists:get_value(type, Config),
+ Port = proplists:get_value(port, Config),
+ Node = proplists:get_value(node, Config),
+ %% Control that authentication required!
+ %% Control that the pages that shall be
+ %% authenticated really need authenticatin
+ ok = httpd_test_lib:verify_request(Type, Host, Port, Node,
+ http_request("GET /ht/open/ ", Version, Host),
+ [{statuscode, 401},
+ {version, Version},
+ {header, "WWW-Authenticate"}]),
+ ok = httpd_test_lib:verify_request(Type, Host, Port, Node,
+ http_request("GET /ht/secret/ ", Version, Host),
+ [{statuscode, 401},
+ {version, Version},
+ {header, "WWW-Authenticate"}]),
+ ok = httpd_test_lib:verify_request(Type, Host, Port, Node,
+ http_request("GET /ht/secret/top_secret/ ",
+ Version, Host),
+ [{statuscode, 401},
+ {version, Version},
+ {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("/ht/open/",
+ "dummy", "WrongPassword", Version, Host), Config,
+ [{statuscode, 401},
+ {header, "WWW-Authenticate"}]),
+ ok = auth_status(auth_request("/ht/open/",
+ "dummy", "WrongPassword", Version, Host), Config,
+ [{statuscode, 401},
+ {header, "WWW-Authenticate"}]),
- 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.
+ %% Control that not just the first user in the list is valid
+ %% Control the first user
+ %% Authennticating ["one:OnePassword" user first in user list]
+ ok = auth_status(auth_request("/ht/open/dummy.html", "one", "OnePassword",
+ Version, Host), Config,
+ [{statuscode, 200}]),
+
+ %% Control the second user
+ %% Authentication OK and a directory listing is supplied!
+ %% ["Aladdin:open sesame" user second in user list]
+ ok = auth_status(auth_request("/ht/open/","Aladdin",
+ "AladdinPassword", Version, Host), Config,
+ [{statuscode, 200}]),
+
+ %% Contro that bad passwords and userids get a good denial
+ %% User correct but wrong password! ["one:one" user first in user list]
+ ok = auth_status(auth_request("/ht/open/", "one", "one", Version, Host), Config,
+ [{statuscode, 401}]),
+ %% Neither user or password correct! ["dummy:dummy"]
+ ok = auth_status(auth_request("/ht/open/", "dummy", "dummy", Version, Host), Config,
+ [{statuscode, 401}]),
+
+ %% Control that authetication still works, even if its a member in a group
+ %% Authentication OK! ["two:TwoPassword" user in first group]
+ ok = auth_status(auth_request("/ht/secret/dummy.html", "two",
+ "TwoPassword", Version, Host), Config,
+ [{statuscode, 200}]),
+
+ %% Authentication OK and a directory listing is supplied!
+ %% ["three:ThreePassword" user in second group]
+ ok = auth_status(auth_request("/ht/secret/", "three",
+ "ThreePassword", Version, Host), Config,
+ [{statuscode, 200}]),
+
+ %% Deny users with bad passwords even if the user is a group member
+ %% User correct but wrong password! ["two:two" user in first group]
+ ok = auth_status(auth_request("/ht/secret/", "two", "two", Version, Host), Config,
+ [{statuscode, 401}]),
+ %% Neither user or password correct! ["dummy:dummy"]
+ ok = auth_status(auth_request("/ht/secret/", "dummy", "dummy", Version, Host), Config,
+ [{statuscode, 401}]),
+
+ %% control that we deny the users that are in subnet above the allowed
+ ok = auth_status(auth_request("/ht/blocknet/dummy.html", "four",
+ "FourPassword", Version, Host), Config,
+ [{statuscode, 403}]),
+ %% Control that we only applies the rules to the right methods
+ ok = httpd_test_lib:verify_request(Type, Host, Port, Node,
+ http_request("HEAD /ht/blocknet/dummy.html ", Version, Host),
+ [{statuscode, head_status(Version)},
+ {version, Version}]),
+
+ %% Control that the rerquire directive can be overrideen
+ ok = auth_status(auth_request("/ht/secret/top_secret/ ", "Aladdin", "AladdinPassword",
+ Version, Host), Config,
+ [{statuscode, 401}]),
+
+ %% Authentication still required!
+ ok = httpd_test_lib:verify_request(Type, Host, Port, Node,
+ http_request("GET /ht/open/ ", Version, Host),
+ [{statuscode, 401},
+ {version, Version},
+ {header, "WWW-Authenticate"}]),
+ ok = httpd_test_lib:verify_request(Type, Host, Port, Node,
+ http_request("GET /ht/secret/ ", Version, Host),
+ [{statuscode, 401},
+ {version, Version},
+ {header, "WWW-Authenticate"}]),
+ ok = httpd_test_lib:verify_request(Type, Host, Port, Node,
+ http_request("GET /ht/secret/top_secret/ ", Version, Host),
+ [{statuscode, 401},
+ {version, Version},
+ {header, "WWW-Authenticate"}]).
+
+%%-------------------------------------------------------------------------
+host() ->
+ [{doc, "Test host header"}].
+
+host(Config) when is_list(Config) ->
+ Cb = proplists:get_value(version_cb, Config),
+ Cb:host(proplists:get_value(type, Config), proplists:get_value(port, Config),
+ proplists:get_value(host, Config), proplists:get_value(node, Config)).
+%%-------------------------------------------------------------------------
+chunked() ->
+ [{doc, "Check that the server accepts chunked requests."}].
+
+chunked(Config) when is_list(Config) ->
+ httpd_1_1:chunked(proplists:get_value(type, Config), proplists:get_value(port, Config),
+ proplists:get_value(host, Config), proplists:get_value(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(proplists:get_value(type, Config), proplists:get_value(port, Config),
+ proplists:get_value(host, Config), proplists:get_value(node, Config)).
+%%-------------------------------------------------------------------------
+max_clients_1_1() ->
+ [{doc, "Test max clients limit"}].
+
+max_clients_1_1(Config) when is_list(Config) ->
+ do_max_clients([{http_version, "HTTP/1.1"} | Config]).
+
+max_clients_1_0() ->
+ [{doc, "Test max clients limit"}].
+
+max_clients_1_0(Config) when is_list(Config) ->
+ do_max_clients([{http_version, "HTTP/1.0"} | Config]).
+
+max_clients_0_9() ->
+ [{doc, "Test max clients limit"}].
+
+max_clients_0_9(Config) when is_list(Config) ->
+ do_max_clients([{http_version, "HTTP/0.9"} | Config]).
+%%-------------------------------------------------------------------------
+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"}]),
+ ok = http_status("GET /cgi-bin/erl/httpd_example:peer ",
+ Config, [{statuscode, 200},
+ {header, "peer-cert-exist", peer(Config)}]).
+
%%-------------------------------------------------------------------------
-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.
+mod_esi_chunk_timeout(Config) when is_list(Config) ->
+ ok = httpd_1_1:mod_esi_chunk_timeout(proplists:get_value(type, Config),
+ proplists:get_value(port, Config),
+ proplists:get_value(host, Config),
+ proplists:get_value(node, Config)).
%%-------------------------------------------------------------------------
-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.
+cgi() ->
+ [{doc, "Test mod_cgi"}].
-%%-------------------------------------------------------------------------
-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
+cgi(Config) when is_list(Config) ->
+ {Script, Script2, Script3} =
+ case test_server:os_type() of
+ {win32, _} ->
+ {"printenv.bat", "printenv.sh", "cgi_echo.exe"};
+ _ ->
+ {"printenv.sh", "printenv.bat", "cgi_echo"}
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.
+ %%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}]),
-%%-------------------------------------------------------------------------
-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
+ ok = http_status("GET /cgi-bin/not_there ", Config,
+ [{statuscode, 404}, {statuscode, 500}]),
+
+ ok = http_status("GET /cgi-bin/"++ Script ++ "?Nisse:kkk?sss/lll ",
+ Config,
+ [{statuscode, 200}]),
+
+ ok = http_status("POST /cgi-bin/"++ Script ++ " ", Config,
+ [{statuscode, 200}]),
+
+ ok = http_status("GET /htbin/"++ Script ++ " ", Config,
+ [{statuscode, 200}]),
+
+ ok = http_status("GET /htbin/not_there ", Config,
+ [{statuscode, 404},{statuscode, 500}]),
+
+ ok = http_status("GET /htbin/"++ Script ++ "?Nisse:kkk?sss/lll ", Config,
+ [{statuscode, 200}]),
+
+ ok = http_status("POST /htbin/"++ Script ++ " ", Config,
+ [{statuscode, 200}]),
+
+ ok = http_status("POST /htbin/"++ Script ++ " ", Config,
+ [{statuscode, 200}]),
+
+ %% Execute an existing, but bad CGI script..
+ ok = http_status("POST /htbin/"++ Script2 ++ " ", Config,
+ [{statuscode, 404}]),
+
+ ok = http_status("POST /cgi-bin/"++ Script2 ++ " ", Config,
+ [{statuscode, 404}]),
+
+ %% Check "ScriptNoCache" directive (default: false)
+ ok = http_status("GET /cgi-bin/" ++ Script ++ " ", Config,
+ [{statuscode, 200},
+ {no_header, "cache-control"}]).
+%%-------------------------------------------------------------------------
+cgi_chunked_encoding_test() ->
+ [{doc, "Test chunked encoding together with mod_cgi "}].
+cgi_chunked_encoding_test(Config) when is_list(Config) ->
+ Host = proplists:get_value(host, Config),
+ Script =
+ case test_server:os_type() of
+ {win32, _} ->
+ "/cgi-bin/printenv.bat";
+ _ ->
+ "/cgi-bin/printenv.sh"
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.
-
-
+ 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(proplists:get_value(type, Config), proplists:get_value(port, Config),
+ Host,
+ proplists:get_value(node, Config),
+ Requests).
%%-------------------------------------------------------------------------
+alias_1_1() ->
+ [{doc, "Test mod_alias"}].
+alias_1_1(Config) when is_list(Config) ->
+ alias([{http_version, "HTTP/1.1"} | Config]).
-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.
-
-
-%%-------------------------------------------------------------------------
-
+alias_1_0() ->
+ [{doc, "Test mod_alias"}].
+
+alias_1_0(Config) when is_list(Config) ->
+ alias([{http_version, "HTTP/1.0"} | Config]).
-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>
+alias_0_9() ->
+ [{doc, "Test mod_alias"}].
+
+alias_0_9(Config) when is_list(Config) ->
+ alias([{http_version, "HTTP/0.9"} | Config]).
+
+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"}]),
- 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.
-
+ ok = http_status("GET / ", Config,
+ [{statuscode, 200},
+ {header, "Content-Type","text/html"},
+ {header, "Server"},
+ {header, "Date"}]),
+
+ 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"}]).
+%%-------------------------------------------------------------------------
+actions() ->
+ [{doc, "Test mod_actions"}].
+
+actions(Config) when is_list(Config) ->
+ ok = http_status("GET /", Config, [{statuscode, 200}]).
+
+%%-------------------------------------------------------------------------
+range() ->
+ [{doc, "Test Range header"}].
+
+range(Config) when is_list(Config) ->
+ httpd_1_1:range(proplists:get_value(type, Config), proplists:get_value(port, Config),
+ proplists:get_value(host, Config), proplists:get_value(node, Config)).
+
+%%-------------------------------------------------------------------------
+if_modified_since() ->
+ [{doc, "Test If-Modified-Since header"}].
+
+if_modified_since(Config) when is_list(Config) ->
+ httpd_1_1:if_test(proplists:get_value(type, Config), proplists:get_value(port, Config),
+ proplists:get_value(host, Config), proplists:get_value(node, Config),
+ proplists:get_value(doc_root, Config)).
+%%-------------------------------------------------------------------------
+trace() ->
+ [{doc, "Test TRACE method"}].
+
+trace(Config) when is_list(Config) ->
+ Cb = proplists:get_value(version_cb, Config),
+ Cb:trace(proplists:get_value(type, Config), proplists:get_value(port, Config),
+ proplists:get_value(host, Config), proplists:get_value(node, Config)).
+%%-------------------------------------------------------------------------
+light() ->
+ ["Test light load"].
+light(Config) when is_list(Config) ->
+ httpd_load:load_test(proplists:get_value(type, Config), proplists:get_value(port, Config), proplists:get_value(host, Config),
+ proplists:get_value(node, Config), 10).
+%%-------------------------------------------------------------------------
+medium() ->
+ ["Test medium load"].
+medium(Config) when is_list(Config) ->
+ httpd_load:load_test(proplists:get_value(type, Config), proplists:get_value(port, Config), proplists:get_value(host, Config),
+ proplists:get_value(node, Config), 100).
+%%-------------------------------------------------------------------------
+heavy() ->
+ ["Test heavy load"].
+heavy(Config) when is_list(Config) ->
+ httpd_load:load_test(proplists:get_value(type, Config), proplists:get_value(port, Config), proplists:get_value(host, Config),
+ proplists:get_value(node, Config),
+ 1000).
+%%-------------------------------------------------------------------------
+content_length() ->
+ ["Tests that content-length is correct OTP-5775"].
+content_length(Config) ->
+ Version = proplists:get_value(http_version, Config),
+ Host = proplists:get_value(host, Config),
+ ok = httpd_test_lib:verify_request(proplists:get_value(type, Config), Host,
+ proplists:get_value(port, Config), proplists:get_value(node, Config),
+ http_request("GET /cgi-bin/erl/httpd_example:get_bin ",
+ Version, Host),
+ [{statuscode, 200},
+ {content_length, 274},
+ {version, Version}]).
+%%-------------------------------------------------------------------------
+bad_hex() ->
+ ["Tests that a URI with a bad hexadecimal code is handled OTP-6003"].
+bad_hex(Config) ->
+ Version = proplists:get_value(http_version, Config),
+ Host = proplists:get_value(host, Config),
+ ok = httpd_test_lib:verify_request(proplists:get_value(type, Config), Host,
+ proplists:get_value(port, Config), proplists:get_value(node, Config),
+ http_request("GET http://www.erlang.org/%skalle ",
+ Version, Host),
+ [{statuscode, 400},
+ {version, Version}]).
+%%-------------------------------------------------------------------------
+missing_CR() ->
+ ["Tests missing CR in delimiter OTP-7304"].
+missing_CR(Config) ->
+ Version = proplists:get_value(http_version, Config),
+ Host = proplists:get_value(host, Config),
+ ok = httpd_test_lib:verify_request(proplists:get_value(type, Config), Host,
+ proplists:get_value(port, Config), proplists:get_value(node, Config),
+ http_request_missing_CR("GET /index.html ", Version, Host),
+ [{statuscode, 200},
+ {version, Version}]).
%%-------------------------------------------------------------------------
+customize() ->
+ [{doc, "Test filtering of headers with custom callback"}].
-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.
-
+customize(Config) when is_list(Config) ->
+ Version = "HTTP/1.1",
+ Host = proplists:get_value(host, Config),
+ Type = proplists:get_value(type, Config),
+ ok = httpd_test_lib:verify_request(proplists:get_value(type, Config), Host,
+ proplists:get_value(port, Config),
+ transport_opts(Type, Config),
+ proplists:get_value(node, Config),
+ http_request("GET /index.html ", Version, Host),
+ [{statuscode, 200},
+ {header, "Content-Type", "text/html"},
+ {header, "Date"},
+ {no_header, "Server"},
+ {version, Version}]).
+
+add_default() ->
+ [{doc, "Test adding default header with custom callback"}].
+
+add_default(Config) when is_list(Config) ->
+ Version = "HTTP/1.1",
+ Host = proplists:get_value(host, Config),
+ Type = proplists:get_value(type, Config),
+ ok = httpd_test_lib:verify_request(proplists:get_value(type, Config), Host,
+ proplists:get_value(port, Config),
+ transport_opts(Type, Config),
+ proplists:get_value(node, Config),
+ http_request("GET /index.html ", Version, Host),
+ [{statuscode, 200},
+ {header, "Content-Type", "text/html"},
+ {header, "Date", "Override-date"},
+ {header, "X-Frame-Options"},
+ {version, Version}]).
+
+%%-------------------------------------------------------------------------
+max_header() ->
+ ["Denial Of Service (DOS) attack, prevented by max_header"].
+max_header(Config) when is_list(Config) ->
+ Version = proplists:get_value(http_version, Config),
+ Host = proplists:get_value(host, Config),
+ case Version of
+ "HTTP/0.9" ->
+ {skip, not_implemented};
+ _ ->
+ dos_hostname(proplists:get_value(type, Config), proplists:get_value(port, Config), Host,
+ proplists:get_value(node, Config), Version, ?MAX_HEADER_SIZE)
+ end.
%%-------------------------------------------------------------------------
-
-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.
-
+max_content_length() ->
+ ["Denial Of Service (DOS) attack, prevented by max_content_length"].
+max_content_length(Config) when is_list(Config) ->
+ Version = proplists:get_value(http_version, Config),
+ Host = proplists:get_value(host, Config),
+ garbage_content_length(proplists:get_value(type, Config), proplists:get_value(port, Config), Host,
+ proplists:get_value(node, Config), Version).
%%-------------------------------------------------------------------------
+security_1_1(Config) when is_list(Config) ->
+ security([{http_version, "HTTP/1.1"} | Config]).
-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.
+security_1_0(Config) when is_list(Config) ->
+ security([{http_version, "HTTP/1.0"} | Config]).
+security() ->
+ ["Test mod_security"].
+security(Config) ->
+ Version = proplists:get_value(http_version, Config),
+ Host = proplists:get_value(host, Config),
+ Port = proplists:get_value(port, Config),
+ Node = proplists:get_value(node, Config),
+ ServerRoot = proplists:get_value(server_root, Config),
-%%-------------------------------------------------------------------------
+ global:register_name(mod_security_test, self()), % Receive events
-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.
+ ct:sleep(5000),
+ OpenDir = filename:join([ServerRoot, "htdocs", "open"]),
-%%-------------------------------------------------------------------------
-
-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.
+ %% Test blocking / unblocking of users.
+ %% /open, require user one Aladdin
+ remove_users(Node, ServerRoot, Host, Port, "", "open"),
-%%-------------------------------------------------------------------------
+ ok = auth_status(auth_request("/open/",
+ "one", "onePassword", Version, Host), Config,
+ [{statuscode, 401}]),
+
+ receive_security_event({event, auth_fail, Port, OpenDir,
+ [{user, "one"}, {password, "onePassword"}]},
+ Node, Port),
+
+ ok = auth_status(auth_request("/open/",
+ "two", "twoPassword", Version, Host), Config,
+ [{statuscode, 401}]),
+
+ receive_security_event({event, auth_fail, Port, OpenDir,
+ [{user, "two"}, {password, "twoPassword"}]},
+ Node, Port),
+ ok = auth_status(auth_request("/open/",
+ "Aladdin", "AladdinPassword", Version, Host),
+ Config, [{statuscode, 401}]),
+
+ receive_security_event({event, auth_fail, Port, OpenDir,
+ [{user, "Aladdin"},
+ {password, "AladdinPassword"}]},
+ Node, Port),
-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),
+ add_user(Node, ServerRoot, Port, "", "open", "one", "onePassword", []),
+ add_user(Node, ServerRoot, Port, "", "open", "two", "twoPassword", []),
- ok.
+ ok = auth_status(auth_request("/open/", "one", "WrongPassword", Version, Host), Config,
+ [{statuscode, 401}]),
+
+ receive_security_event({event, auth_fail, Port, OpenDir,
+ [{user, "one"}, {password, "WrongPassword"}]},
+ Node, Port),
+ ok = auth_status(auth_request("/open/", "one", "WrongPassword", Version, Host), Config,
+ [{statuscode, 401}]),
+
+ receive_security_event({event, auth_fail, Port, OpenDir,
+ [{user, "one"}, {password, "WrongPassword"}]},
+ Node, Port),
+ receive_security_event({event, user_block, Port, OpenDir,
+ [{user, "one"}]}, Node, Port),
+
+ global:unregister_name(mod_security_test), % No more events.
+
+ ok = auth_status(auth_request("/open/", "one", "WrongPassword", Version, Host), Config,
+ [{statuscode, 401}]),
+
+ %% User "one" should be blocked now..
+ case list_blocked_users(Node, Port) of
+ [{"one",_, Port, OpenDir,_}] ->
+ ok;
+ Blocked ->
+ ct:fail({unexpected_blocked, Blocked})
+ end,
-%%-------------------------------------------------------------------------
+ [{"one",_, Port, OpenDir,_}] = list_blocked_users(Node, Port, OpenDir),
+ true = unblock_user(Node, "one", Port, OpenDir),
+ %% User "one" should not be blocked any more.
-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).
+ [] = list_blocked_users(Node, Port),
-ssl_block_disturbing_blocker_dies(Tag, Config) ->
- httpd_block:disturbing_blocker_dies(Tag,
- ?SSL_PORT,
- ?config(host, Config),
- ?config(node, Config)),
- ok.
+ ok = auth_status(auth_request("/open/", "one", "onePassword", Version, Host), Config,
+ [{statuscode, 200}]),
+ %% Test list_auth_users & auth_timeout
-%%-------------------------------------------------------------------------
+ ["one"] = list_auth_users(Node, Port),
-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.
+ ok = auth_status(auth_request("/open/", "two", "onePassword", Version, Host), Config,
+ [{statuscode, 401}]),
+ ["one"] = list_auth_users(Node, Port),
-%%-------------------------------------------------------------------------
+
+ ["one"] = list_auth_users(Node, Port, OpenDir),
+
+ ok = auth_status(auth_request("/open/", "two", "twoPassword", Version, Host), Config,
+ [{statuscode, 401}]),
-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).
+ ["one"] = list_auth_users(Node, Port),
-ssl_restart_no_block(Tag, Config) ->
- httpd_block:restart_no_block(Tag,
- ?SSL_PORT,
- ?config(host, Config),
- ?config(node, Config)),
- ok.
+
+ ["one"] = list_auth_users(Node, Port, OpenDir),
+ %% Wait for successful auth to timeout.
+ ct:sleep(?AUTH_TIMEOUT*1001),
-%%-------------------------------------------------------------------------
+ [] = list_auth_users(Node, Port),
+ [] = list_auth_users(Node, Port, OpenDir),
-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>
+ %% "two" is blocked.
- httpd_block:restart_disturbing_block(Tag, ?SSL_PORT,
- ?config(host, Config),
- ?config(node, Config)),
- ok.
+ true = unblock_user(Node, "two", Port, OpenDir),
-%%-------------------------------------------------------------------------
+ %% Test explicit blocking. Block user 'two'.
+ [] = list_blocked_users(Node,Port,OpenDir),
-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>
+ true = block_user(Node, "two", Port, OpenDir, 10),
- httpd_block:restart_non_disturbing_block(Tag,
- ?SSL_PORT,
- ?config(host, Config),
- ?config(node, Config)),
- ok.
+ ok = auth_status(auth_request("/open/", "two", "twoPassword", Version, Host), Config,
+ [{statuscode, 401}]),
+
+ true = unblock_user(Node, "two", Port, OpenDir).
+
+%%-------------------------------------------------------------------------
+non_disturbing_reconfiger_dies(Config) when is_list(Config) ->
+ do_reconfiger_dies([{http_version, "HTTP/1.1"} | Config], non_disturbing).
+disturbing_reconfiger_dies(Config) when is_list(Config) ->
+ do_reconfiger_dies([{http_version, "HTTP/1.1"} | Config], disturbing).
+
+do_reconfiger_dies(Config, DisturbingType) ->
+ Server = proplists:get_value(server_pid, Config),
+ Version = proplists:get_value(http_version, Config),
+ Host = proplists:get_value(host, Config),
+ Port = proplists:get_value(port, Config),
+ Type = proplists:get_value(type, Config),
+
+ HttpdConfig = httpd:info(Server),
+ BlockRequest = http_request("GET /eval?httpd_example:delay(2000) ", Version, Host),
+ {ok, Socket} = inets_test_lib:connect_bin(Type, Host, Port, transport_opts(Type, Config)),
+ inets_test_lib:send(Type, Socket, BlockRequest),
+ ct:sleep(100), %% Avoid possible timing issues
+ Pid = spawn(fun() -> httpd:reload_config([{server_name, "httpd_kill_" ++ Version},
+ {port, Port}|
+ proplists:delete(server_name, HttpdConfig)], DisturbingType)
+ end),
+
+ monitor(process, Pid),
+ exit(Pid, kill),
+ receive
+ {'DOWN', _, _, _, _} ->
+ ok
+ end,
+ inets_test_lib:close(Type, Socket),
+ [{server_name, "httpd_test"}] = httpd:info(Server, [server_name]).
+%%-------------------------------------------------------------------------
+disturbing_1_1(Config) when is_list(Config) ->
+ disturbing([{http_version, "HTTP/1.1"} | Config]).
+
+disturbing_1_0(Config) when is_list(Config) ->
+ disturbing([{http_version, "HTTP/1.0"} | Config]).
+
+disturbing_0_9(Config) when is_list(Config) ->
+ disturbing([{http_version, "HTTP/0.9"} | Config]).
+
+disturbing(Config) when is_list(Config)->
+ Server = proplists:get_value(server_pid, Config),
+ Version = proplists:get_value(http_version, Config),
+ Host = proplists:get_value(host, Config),
+ Port = proplists:get_value(port, Config),
+ Type = proplists:get_value(type, Config),
+ HttpdConfig = httpd:info(Server),
+ BlockRequest = http_request("GET /eval?httpd_example:delay(2000) ", Version, Host),
+ {ok, Socket} = inets_test_lib:connect_bin(Type, Host, Port, transport_opts(Type, Config)),
+ inets_test_lib:send(Type, Socket, BlockRequest),
+ ct:sleep(100), %% Avoid possible timing issues
+ ok = httpd:reload_config([{server_name, "httpd_disturbing_" ++ Version}, {port, Port}|
+ proplists:delete(server_name, HttpdConfig)], disturbing),
+ Close = list_to_atom((typestr(Type)) ++ "_closed"),
+ receive
+ {Close, Socket} ->
+ ok;
+ Msg ->
+ ct:fail({{expected, {Close, Socket}}, {got, Msg}})
+ end,
+ inets_test_lib:close(Type, Socket),
+ [{server_name, "httpd_disturbing_" ++ Version}] = httpd:info(Server, [server_name]).
+%%-------------------------------------------------------------------------
+non_disturbing_1_1(Config) when is_list(Config) ->
+ non_disturbing([{http_version, "HTTP/1.1"} | Config]).
+
+non_disturbing_1_0(Config) when is_list(Config) ->
+ non_disturbing([{http_version, "HTTP/1.0"} | Config]).
+
+non_disturbing_0_9(Config) when is_list(Config) ->
+ non_disturbing([{http_version, "HTTP/0.9"} | Config]).
+
+non_disturbing(Config) when is_list(Config)->
+ Server = proplists:get_value(server_pid, Config),
+ Version = proplists:get_value(http_version, Config),
+ Host = proplists:get_value(host, Config),
+ Port = proplists:get_value(port, Config),
+ Type = proplists:get_value(type, Config),
+
+ HttpdConfig = httpd:info(Server),
+ BlockRequest = http_request("GET /eval?httpd_example:delay(2000) ", Version, Host),
+ {ok, Socket} = inets_test_lib:connect_bin(Type, Host, Port, transport_opts(Type, Config)),
+ inets_test_lib:send(Type, Socket, BlockRequest),
+ ct:sleep(100), %% Avoid possible timing issues
+ ok = httpd:reload_config([{server_name, "httpd_non_disturbing_" ++ Version}, {port, Port}|
+ proplists:delete(server_name, HttpdConfig)], non_disturbing),
+ Transport = type(Type),
+ receive
+ {Transport, Socket, Msg} ->
+ ct:pal("Received message ~p~n", [Msg]),
+ ok
+ after 2000 ->
+ ct:fail(timeout)
+ end,
+ inets_test_lib:close(Type, Socket),
+ [{server_name, "httpd_non_disturbing_" ++ Version}] = httpd:info(Server, [server_name]).
+
+%%-------------------------------------------------------------------------
+mime_types_format(Config) when is_list(Config) ->
+ DataDir = proplists:get_value(data_dir, Config),
+ MimeTypes = filename:join(DataDir, "mime_types.txt"),
+ {ok,[{"wrl","x-world/x-vrml"},
+ {"vrml","x-world/x-vrml"},
+ {"ice","x-conference/x-cooltalk"},
+ {"movie","video/x-sgi-movie"},
+ {"avi","video/x-msvideo"},
+ {"qt","video/quicktime"},
+ {"mov","video/quicktime"},
+ {"mpeg","video/mpeg"},
+ {"mpg","video/mpeg"},
+ {"mpe","video/mpeg"},
+ {"sgml","text/x-sgml"},
+ {"sgm","text/x-sgml"},
+ {"etx","text/x-setext"},
+ {"tsv","text/tab-separated-values"},
+ {"rtx","text/richtext"},
+ {"txt","text/plain"},
+ {"html","text/html"},
+ {"htm","text/html"},
+ {"css","text/css"},
+ {"xwd","image/x-xwindowdump"},
+ {"xpm","image/x-xpixmap"},
+ {"xbm","image/x-xbitmap"},
+ {"rgb","image/x-rgb"},
+ {"ppm","image/x-portable-pixmap"},
+ {"pgm","image/x-portable-graymap"},
+ {"pbm","image/x-portable-bitmap"},
+ {"pnm","image/x-portable-anymap"},
+ {"ras","image/x-cmu-raster"},
+ {"tiff","image/tiff"},
+ {"tif","image/tiff"},
+ {"png","image/png"},
+ {"jpeg","image/jpeg"},
+ {"jpg","image/jpeg"},
+ {"jpe","image/jpeg"},
+ {"ief","image/ief"},
+ {"gif","image/gif"},
+ {"pdb","chemical/x-pdb"},
+ {"xyz","chemical/x-pdb"},
+ {"wav","audio/x-wav"},
+ {"ra","audio/x-realaudio"},
+ {"rpm","audio/x-pn-realaudio-plugin"},
+ {"ram","audio/x-pn-realaudio"},
+ {"aif","audio/x-aiff"},
+ {"aiff","audio/x-aiff"},
+ {"aifc","audio/x-aiff"},
+ {"mpga","audio/mpeg"},
+ {"mp2","audio/mpeg"},
+ {"au","audio/basic"},
+ {"snd","audio/basic"},
+ {"zip","application/zip"},
+ {"src","application/x-wais-source"},
+ {"ustar","application/x-ustar"},
+ {"ms","application/x-troff-ms"},
+ {"me","application/x-troff-me"},
+ {"man","application/x-troff-man"},
+ {"t","application/x-troff"},
+ {"tr","application/x-troff"},
+ {"roff","application/x-troff"},
+ {"texinfo","application/x-texinfo"},
+ {"texi","application/x-texinfo"},
+ {"tex","application/x-tex"},
+ {"tcl","application/x-tcl"},
+ {"tar","application/x-tar"},
+ {"sv4crc","application/x-sv4crc"},
+ {"sv4cpio","application/x-sv4cpio"},
+ {"sit","application/x-stuffit"},
+ {"shar","application/x-shar"},
+ {"sh","application/x-sh"},
+ {"nc","application/x-netcdf"},
+ {"cdf","application/x-netcdf"},
+ {"mif","application/x-mif"},
+ {"latex","application/x-latex"},
+ {"skp","application/x-koan"},
+ {"skd","application/x-koan"},
+ {"skt","application/x-koan"},
+ {"skm","application/x-koan"},
+ {"cgi","application/x-httpd-cgi"},
+ {"hdf","application/x-hdf"},
+ {"gz","application/x-gzip"},
+ {"gtar","application/x-gtar"},
+ {"dvi","application/x-dvi"},
+ {"dcr","application/x-director"},
+ {"dir","application/x-director"},
+ {"dxr","application/x-director"},
+ {"csh","application/x-csh"},
+ {"cpio","application/x-cpio"},
+ {"Z","application/x-compress"},
+ {"vcd","application/x-cdlink"},
+ {"bcpio","application/x-bcpio"},
+ {"rtf","application/rtf"},
+ {"ppt","application/powerpoint"},
+ {"ai","application/postscript"},
+ {"eps","application/postscript"},
+ {"ps","application/postscript"},
+ {"pdf","application/pdf"},
+ {"oda","application/oda"},
+ {"bin","application/octet-stream"},
+ {"dms","application/octet-stream"},
+ {"lha","application/octet-stream"},
+ {"lzh","application/octet-stream"},
+ {"exe","application/octet-stream"},
+ {"class","application/octet-stream"},
+ {"doc","application/msword"},
+ {"cpt","application/mac-compactpro"},
+ {"hqx","application/mac-binhex40"}]} = httpd_conf:load_mime_types(MimeTypes).
+%%--------------------------------------------------------------------
+%% Internal functions -----------------------------------
+%%--------------------------------------------------------------------
+url(http, End, Config) ->
+ Port = proplists:get_value(port, Config),
+ {ok,Host} = inet:gethostname(),
+ ?URL_START ++ Host ++ ":" ++ integer_to_list(Port) ++ End.
+
+do_max_clients(Config) ->
+ Version = proplists:get_value(http_version, Config),
+ Host = proplists:get_value(host, Config),
+ Port = proplists:get_value(port, Config),
+ Type = proplists:get_value(type, Config),
+
+ Request = http_request("GET /index.html ", Version, Host),
+ BlockRequest = http_request("GET /eval?httpd_example:delay(2000) ", Version, Host),
+ {ok, Socket} = inets_test_lib:connect_bin(Type, Host, Port, transport_opts(Type, Config)),
+ inets_test_lib:send(Type, Socket, BlockRequest),
+ ct:sleep(100), %% Avoid possible timing issues
+ ok = httpd_test_lib:verify_request(Type, Host,
+ Port,
+ transport_opts(Type, Config),
+ proplists:get_value(node, Config),
+ Request,
+ [{statuscode, 503},
+ {version, Version}]),
+ receive
+ {_, Socket, _Msg} ->
+ ok
+ end,
+ inets_test_lib:close(Type, Socket),
+ ct:sleep(100), %% Avoid possible timing issues
+ ok = httpd_test_lib:verify_request(Type, Host,
+ Port,
+ transport_opts(Type, Config),
+ proplists:get_value(node, Config),
+ Request,
+ [{statuscode, 200},
+ {version, Version}]).
-%%-------------------------------------------------------------------------
-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.
+setup_server_dirs(ServerRoot, DocRoot, DataDir) ->
+ CgiDir = filename:join(ServerRoot, "cgi-bin"),
+ AuthDir = filename:join(ServerRoot, "auth"),
+ PicsDir = filename:join(ServerRoot, "icons"),
+ ConfigDir = filename:join(ServerRoot, "config"),
-%%-------------------------------------------------------------------------
-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 = file:make_dir(ServerRoot),
+ ok = file:make_dir(DocRoot),
+ ok = file:make_dir(CgiDir),
+ ok = file:make_dir(AuthDir),
+ ok = file:make_dir(PicsDir),
+ ok = file:make_dir(ConfigDir),
+
+ 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"),
+ ConfigSrc = filename:join(DataDir, "server_root/config"),
- 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"}]),
+ 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),
+ inets_test_lib:copy_dirs(ConfigSrc, ConfigDir),
+
+ Cgi = case test_server:os_type() of
+ {win32, _} ->
+ "cgi_echo.exe";
+ _ ->
+ "cgi_echo"
+ end,
- 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"}]),
+ 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}),
- 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,
+ 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}).
- {ok,FI}=file:read_file_info(File),
+start_apps(Group) when Group == https_basic;
+ Group == https_limit;
+ Group == https_custom;
+ Group == https_basic_auth;
+ Group == https_auth_api;
+ Group == https_auth_api_dets;
+ Group == https_auth_api_mnesia;
+ Group == https_htaccess;
+ Group == https_security;
+ Group == https_reload
+ ->
+ inets_test_lib:start_apps([inets, asn1, crypto, public_key, ssl]);
+start_apps(Group) when Group == http_basic;
+ Group == http_limit;
+ Group == http_custom;
+ Group == http_basic_auth;
+ Group == http_auth_api;
+ Group == http_auth_api_dets;
+ Group == http_auth_api_mnesia;
+ Group == http_htaccess;
+ Group == http_security;
+ Group == http_reload;
+ Group == http_mime_types->
+ inets_test_lib:start_apps([inets]).
+
+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)}.
+
+init_ssl(Group, Config) ->
+ PrivDir = proplists:get_value(priv_dir, Config),
+ CaKey = {_Trusted,_} =
+ erl_make_certs:make_cert([{key, dsa},
+ {subject,
+ [{name, "Public Key"},
+ {?'id-at-name',
+ {printableString, "public_key"}},
+ {?'id-at-pseudonym',
+ {printableString, "pubkey"}},
+ {city, "Stockholm"},
+ {country, "SE"},
+ {org, "erlang"},
+ {org_unit, "testing dep"}
+ ]}
+ ]),
+ ok = erl_make_certs:write_pem(PrivDir, "public_key_cacert", CaKey),
- case file:write_file_info(File,FI#file_info{mtime=Bad_mtime}) of
+ CertK1 = {_Cert1, _} = erl_make_certs:make_cert([{issuer, CaKey}]),
+ CertK2 = {_Cert2,_} = erl_make_certs:make_cert([{issuer, CertK1},
+ {digest, md5},
+ {extensions, false}]),
+ ok = erl_make_certs:write_pem(PrivDir, "public_key_cert", CertK2),
+
+ case start_apps(Group) 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_last_modified,
- "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}
+ init_httpd(Group, [{type, ssl} | Config]);
+ _ ->
+ {skip, "Could not start https apps"}
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),
+server_config(http_basic, Config) ->
+ basic_conf() ++ server_config(http, Config);
+server_config(https_basic, Config) ->
+ basic_conf() ++ server_config(https, Config);
+server_config(http_reload, Config) ->
+ [{keep_alive_timeout, 2}] ++ server_config(http, Config);
+server_config(https_reload, Config) ->
+ [{keep_alive_timeout, 2}] ++ server_config(https, Config);
+server_config(http_limit, Config) ->
+ Conf = [{max_clients, 1},
+ %% Make sure option checking code is run
+ {max_content_length, 100000002}] ++ server_config(http, Config),
+ ct:pal("Received message ~p~n", [Conf]),
+ Conf;
+server_config(http_custom, Config) ->
+ [{customize, ?MODULE}] ++ server_config(http, Config);
+server_config(https_custom, Config) ->
+ [{customize, ?MODULE}] ++ server_config(https, Config);
+server_config(https_limit, Config) ->
+ [{max_clients, 1}] ++ server_config(https, Config);
+server_config(http_basic_auth, Config) ->
+ ServerRoot = proplists:get_value(server_root, Config),
+ auth_conf(ServerRoot) ++ server_config(http, Config);
+server_config(https_basic_auth, Config) ->
+ ServerRoot = proplists:get_value(server_root, Config),
+ auth_conf(ServerRoot) ++ server_config(https, Config);
+server_config(http_auth_api, Config) ->
+ ServerRoot = proplists:get_value(server_root, Config),
+ auth_api_conf(ServerRoot, plain) ++ server_config(http, Config);
+server_config(https_auth_api, Config) ->
+ ServerRoot = proplists:get_value(server_root, Config),
+ auth_api_conf(ServerRoot, plain) ++ server_config(https, Config);
+server_config(http_auth_api_dets, Config) ->
+ ServerRoot = proplists:get_value(server_root, Config),
+ auth_api_conf(ServerRoot, dets) ++ server_config(http, Config);
+server_config(https_auth_api_dets, Config) ->
+ ServerRoot = proplists:get_value(server_root, Config),
+ auth_api_conf(ServerRoot, dets) ++ server_config(https, Config);
+server_config(http_auth_api_mnesia, Config) ->
+ ServerRoot = proplists:get_value(server_root, Config),
+ auth_api_conf(ServerRoot, mnesia) ++ server_config(http, Config);
+server_config(https_auth_api_mnesia, Config) ->
+ ServerRoot = proplists:get_value(server_root, Config),
+ auth_api_conf(ServerRoot, mnesia) ++ server_config(https, Config);
+server_config(http_htaccess, Config) ->
+ auth_access_conf() ++ server_config(http, Config);
+server_config(https_htaccess, Config) ->
+ auth_access_conf() ++ server_config(https, Config);
+server_config(http_security, Config) ->
+ ServerRoot = proplists:get_value(server_root, Config),
+ tl(auth_conf(ServerRoot)) ++ security_conf(ServerRoot) ++ server_config(http, Config);
+server_config(https_security, Config) ->
+ ServerRoot = proplists:get_value(server_root, Config),
+ tl(auth_conf(ServerRoot)) ++ security_conf(ServerRoot) ++ server_config(https, Config);
+server_config(http_mime_types, Config0) ->
+ Config1 = basic_conf() ++ server_config(http, Config0),
+ ServerRoot = proplists:get_value(server_root, Config0),
+ MimeTypesFile = filename:join([ServerRoot,"config", "mime.types"]),
+ [{mime_types, MimeTypesFile} | proplists:delete(mime_types, Config1)];
+
+server_config(http, Config) ->
+ ServerRoot = proplists:get_value(server_root, Config),
+ [{port, 0},
+ {socket_type, {ip_comm, [{nodelay, true}]}},
+ {server_name,"httpd_test"},
+ {server_root, ServerRoot},
+ {document_root, proplists:get_value(doc_root, Config)},
+ {bind_address, any},
+ {ipfamily, proplists:get_value(ipfamily, Config)},
+ {max_header_size, 256},
+ {max_header_action, close},
+ {directory_index, ["index.html", "welcome.html"]},
+ {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]}}
+ ];
+
+server_config(https, Config) ->
+ PrivDir = proplists:get_value(priv_dir, Config),
+ [{socket_type, {essl,
+ [{nodelay, true},
+ {cacertfile,
+ filename:join(PrivDir, "public_key_cacert.pem")},
+ {certfile,
+ filename:join(PrivDir, "public_key_cert.pem")},
+ {keyfile,
+ filename:join(PrivDir, "public_key_cert_key.pem")}
+ ]}}] ++ proplists:delete(socket_type, server_config(http, Config)).
+
+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].
+
+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".
+
+http_request_missing_CR(Request, "HTTP/1.1" = Version, Host) ->
+ Request ++ Version ++ "\r\nhost:" ++ Host ++ "\r\n\r\n\n";
+http_request_missing_CR(Request, Version, _) ->
+ Request ++ Version ++ "\r\n\n".
+
+head_status("HTTP/0.9") ->
+ 501; %% Not implemented in HTTP/0.9
+head_status(_) ->
+ 200.
+
+basic_conf() ->
+ [{modules, [mod_alias, mod_range, mod_responsecontrol,
+ mod_trace, mod_esi, mod_cgi, mod_dir, mod_get, mod_head]}].
+
+auth_access_conf() ->
+ [{modules, [mod_alias, mod_htaccess, mod_dir, mod_get, mod_head]},
+ {access_files, [".htaccess"]}].
+
+auth_conf(Root) ->
+ [{modules, [mod_alias, mod_auth, mod_dir, mod_get, mod_head]},
+ {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"]}]}}].
+
+auth_api_conf(Root, plain) ->
+ [{modules, [mod_alias, mod_auth, mod_dir, mod_get, mod_head]},
+ {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"]}]}}];
+
+auth_api_conf(Root, dets) ->
[
- 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"])
+ {modules, [mod_alias, mod_auth, mod_dir, mod_get, mod_head]},
+ {directory, {filename:join(Root, "htdocs/dets_open"),
+ [{auth_type, dets},
+ {auth_name, "Dets Open Area"},
+ {auth_user_file, filename:join(Root, "passwd")},
+ {auth_group_file, filename:join(Root, "group")},
+ {require_user, ["one", "Aladdin"]}]}},
+ {directory, {filename:join(Root, "htdocs/dets_secret"),
+ [{auth_type, dets},
+ {auth_name, "Dests Secret Area"},
+ {auth_user_file, filename:join(Root, "passwd")},
+ {auth_group_file, filename:join(Root, "group")},
+ {require_group, ["group1", "group2"]}]}},
+ {directory, {filename:join(Root, "htdocs/dets_secret/top_secret"),
+ [{auth_type, dets},
+ {auth_name, "Dets Top Secret Area"},
+ {auth_user_file, filename:join(Root, "passwd")},
+ {auth_group_file, filename:join(Root, "group")},
+ {require_group, ["group3"]}]}}
+ ];
+
+auth_api_conf(Root, mnesia) ->
+ [{modules, [mod_alias, mod_auth, mod_dir, mod_get, mod_head]},
+ {directory, {filename:join(Root, "htdocs/mnesia_open"),
+ [{auth_type, mnesia},
+ {auth_name, "Mnesia Open Area"},
+ {require_user, ["one", "Aladdin"]}]}},
+ {directory, {filename:join(Root, "htdocs/mnesia_secret"),
+ [{auth_type, mnesia},
+ {auth_name, "Mnesia Secret Area"},
+ {require_group, ["group1", "group2"]}]}},
+ {directory, {filename:join(Root, "htdocs/mnesia_secret/top_secret"),
+ [{auth_type, mnesia},
+ {auth_name, "Mnesia Top Secret Area"},
+ {require_group, ["group3"]}]}}].
+
+security_conf(Root) ->
+ SecFile = filename:join(Root, "security_data"),
+ Open = filename:join(Root, "htdocs/open"),
+ Secret = filename:join(Root, "htdocs/secret"),
+ TopSecret = filename:join(Root, "htdocs/secret/top_secret"),
+
+ [{modules, [mod_alias, mod_auth, mod_security, mod_dir, mod_get, mod_head]},
+ {security_directory, {Open,
+ [{auth_name, "Open Area"},
+ {auth_user_file, filename:join(Root, "auth/passwd")},
+ {auth_group_file, filename:join(Root, "auth/group")},
+ {require_user, ["one", "Aladdin"]} |
+ mod_security_conf(SecFile, Open)]}},
+ {security_directory, {Secret,
+ [{auth_name, "Secret Area"},
+ {auth_user_file, filename:join(Root, "auth/passwd")},
+ {auth_group_file, filename:join(Root, "auth/group")},
+ {require_group, ["group1", "group2"]} |
+ mod_security_conf(SecFile, Secret)]}},
+ {security_directory, {TopSecret,
+ [{auth_name, "Top Secret Area"},
+ {auth_user_file, filename:join(Root, "auth/passwd")},
+ {auth_group_file, filename:join(Root, "auth/group")},
+ {require_group, ["group3"]} |
+ mod_security_conf(SecFile, TopSecret)]}}].
+
+mod_security_conf(SecFile, Dir) ->
+ [{data_file, SecFile},
+ {max_retries, 3},
+ {fail_expire_time, ?FAIL_EXPIRE_TIME},
+ {block_time, 1},
+ {auth_timeout, ?AUTH_TIMEOUT},
+ {callback_module, ?MODULE},
+ {path, Dir} %% This is should not be needed, but is atm, awful design!
].
+
-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])).
+http_status(Request, Config, Expected) ->
+ Version = proplists:get_value(http_version, Config),
+ Host = proplists:get_value(host, Config),
+ Type = proplists:get_value(type, Config),
+ httpd_test_lib:verify_request(proplists:get_value(type, Config), Host,
+ proplists:get_value(port, Config),
+ transport_opts(Type, Config),
+ proplists:get_value(node, Config),
+ http_request(Request, Version, Host),
+ Expected ++ [{version, Version}]).
+
+http_status(Request, HeadersAndBody, Config, Expected) ->
+ Version = proplists:get_value(http_version, Config),
+ Host = proplists:get_value(host, Config),
+ Type = proplists:get_value(type, Config),
+ httpd_test_lib:verify_request(proplists:get_value(type, Config), Host,
+ proplists:get_value(port, Config),
+ transport_opts(Type, Config),
+ proplists:get_value(node, Config),
+ http_request(Request, Version, Host, HeadersAndBody),
+ Expected ++ [{version, Version}]).
+
+auth_status(AuthRequest, Config, Expected) ->
+ Version = proplists:get_value(http_version, Config),
+ Host = proplists:get_value(host, Config),
+ Type = proplists:get_value(type, Config),
+ httpd_test_lib:verify_request(proplists:get_value(type, Config), Host,
+ proplists:get_value(port, Config),
+ transport_opts(Type, Config),
+ proplists:get_value(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.
@@ -2251,6 +1887,29 @@ cleanup_mnesia() ->
mnesia:delete_schema([node()]),
ok.
+transport_opts(ssl, Config) ->
+ PrivDir = proplists:get_value(priv_dir, Config),
+ [proplists:get_value(ipfamily, Config),
+ {cacertfile, filename:join(PrivDir, "public_key_cacert.pem")}];
+transport_opts(_, Config) ->
+ [proplists:get_value(ipfamily, Config)].
+
+
+%%% mod_range
+create_range_data(Path) ->
+ PathAndFileName=filename:join([Path,"range.txt"]),
+ case file:read_file(PathAndFileName) of
+ {error, enoent} ->
+ file:write_file(PathAndFileName,list_to_binary(["12345678901234567890",
+ "12345678901234567890",
+ "12345678901234567890",
+ "12345678901234567890",
+ "12345678901234567890"]));
+ _ ->
+ ok
+ end.
+
+%%% mod_htaccess
create_htaccess_data(Path, IpAddress)->
create_htaccess_dirs(Path),
@@ -2347,99 +2006,189 @@ remove_htaccess(Path)->
file:delete(filename:join([Path,"ht","groups.file"])),
remove_htaccess_dirs(Path).
+dos_hostname(Type, Port, Host, Node, Version, Max) ->
+ TooLongHeader = lists:append(lists:duplicate(Max + 1, "a")),
+
+ ok = httpd_test_lib:verify_request(Type, Host, Port, Node,
+ dos_hostname_request("", Version),
+ [{statuscode, 200},
+ {version, Version}]),
+
+ ok = httpd_test_lib:verify_request(Type, Host, Port, Node,
+ dos_hostname_request("dummy-host.ericsson.se", Version),
+ [{statuscode, 200},
+ {version, Version}]),
+
+ ok = httpd_test_lib:verify_request(Type, Host, Port, Node,
+ dos_hostname_request(TooLongHeader, Version),
+ [{statuscode, request_entity_too_large_code(Version)},
+ {version, Version}]).
+dos_hostname_request(Host, Version) ->
+ dos_http_request("GET / ", Version, Host).
+
+dos_http_request(Request, "HTTP/1.1" = Version, Host) ->
+ http_request(Request, Version, Host);
+dos_http_request(Request, Version, Host) ->
+ Request ++ Version ++ "\r\nhost:" ++ Host ++ "\r\n\r\n".
+
+request_entity_too_large_code("HTTP/1.0") ->
+ 403; %% 413 not defined in HTTP/1.0
+request_entity_too_large_code(_) ->
+ 413.
+
+length_required_code("HTTP/1.0") ->
+ 403; %% 411 not defined in HTTP/1.0
+length_required_code(_) ->
+ 411.
+
+garbage_content_length(Type, Port, Host, Node, Version) ->
+ ok = httpd_test_lib:verify_request(Type, Host, Port, Node,
+ garbage_content_length_request("GET / ", Version, Host, "aaaa"),
+ [{statuscode, length_required_code(Version)},
+ {version, Version}]),
+ ok = httpd_test_lib:verify_request(Type, Host, Port, Node,
+ garbage_content_length_request("GET / ", Version, Host,
+ lists:duplicate($a, 100)),
+ [{statuscode, request_entity_too_large_code(Version)},
+ {version, Version}]).
+
+garbage_content_length_request(Request, Version, Host, Garbage) ->
+ http_request(Request, Version, Host,
+ {"content-length:" ++ Garbage, "Body with garbage content length indicator"}).
+
+
+update_password(Node, ServerRoot, _Address, Port, AuthPrefix, Dir, Old, New)->
+ Directory = filename:join([ServerRoot, "htdocs", AuthPrefix ++ Dir]),
+ rpc:call(Node, mod_auth, update_password,
+ [undefined, Port, Directory, Old, New, New]).
+
+add_user(Node, Root, Port, AuthPrefix, Dir, User, Password, UserData) ->
+ Addr = undefined,
+ Directory = filename:join([Root, "htdocs", AuthPrefix ++ Dir]),
+ rpc:call(Node, mod_auth, add_user,
+ [User, Password, UserData, Addr, Port, Directory]).
+
+
+delete_user(Node, Root, _Host, Port, AuthPrefix, Dir, User) ->
+ Addr = undefined,
+ Directory = filename:join([Root, "htdocs", AuthPrefix ++ Dir]),
+ rpc:call(Node, mod_auth, delete_user, [User, Addr, Port, Directory]).
+remove_users(Node, ServerRoot, Host, Port, AuthPrefix, Dir) ->
+ %% List users, delete them, and make sure they are gone.
+ case list_users(Node, ServerRoot, Host, Port, AuthPrefix, Dir) of
+ {ok, Users} ->
+ lists:foreach(fun(User) ->
+ delete_user(Node, ServerRoot, Host,
+ Port, AuthPrefix, Dir, User)
+ end,
+ Users),
+ {ok, []} = list_users(Node, ServerRoot, Host, Port, AuthPrefix, Dir);
+ _ ->
+ ok
+ end.
+
+list_users(Node, Root, _Host, Port, AuthPrefix, Dir) ->
+ Addr = undefined,
+ Directory = filename:join([Root, "htdocs", AuthPrefix ++ Dir]),
+ rpc:call(Node, mod_auth, list_users, [Addr, Port, Directory]).
+
+remove_groups(Node, ServerRoot, Host, Port, AuthPrefix, Dir) ->
+ {ok, Groups} = list_groups(Node, ServerRoot, Host, Port, AuthPrefix, Dir),
+ lists:foreach(fun(Group) ->
+ delete_group(Node, Group, Port, ServerRoot, AuthPrefix, Dir)
+ end,
+ Groups),
+ {ok, []} = list_groups(Node, ServerRoot, Host, Port, AuthPrefix, Dir).
+
+delete_group(Node, Group, Port, Root, AuthPrefix, Dir) ->
+ Addr = undefined,
+ Directory = filename:join([Root, "htdocs", AuthPrefix ++ Dir]),
+ rpc:call(Node, mod_auth, delete_group, [Group, Addr, Port, Directory]).
+
+list_groups(Node, Root, _, Port, AuthPrefix, Dir) ->
+ Addr = undefined,
+ Directory = filename:join([Root, "htdocs", AuthPrefix ++ Dir]),
+ rpc:call(Node, mod_auth, list_groups, [Addr, Port, Directory]).
+
+add_group_member(Node, Root, Port, AuthPrefix, Dir, User, Group) ->
+ Addr = undefined,
+ Directory = filename:join([Root, "htdocs", AuthPrefix ++ Dir]),
+ rpc:call(Node, mod_auth, add_group_member, [Group, User, Addr, Port,
+ Directory]).
+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])).
+
+receive_security_event(Event, Node, Port) ->
+ receive
+ Event ->
+ ok;
+ {'EXIT', _, _} ->
+ receive_security_event(Event, Node, Port)
+ after 5000 ->
+ %% Flush the message queue, to see if we got something...
+ inets_test_lib:flush()
+ end.
-dos_hostname_poll(Type, Host, Port, Node, Hosts) ->
- [dos_hostname_poll1(Type, Host, Port, Node, Host1, Code)
- || {Host1,Code} <- Hosts].
+list_blocked_users(Node,Port) ->
+ Addr = undefined, % Assumed to be on the same host
+ rpc:call(Node, mod_security, list_blocked_users, [Addr,Port]).
-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".
+list_blocked_users(Node,Port,Dir) ->
+ Addr = undefined, % Assumed to be on the same host
+ rpc:call(Node, mod_security, list_blocked_users, [Addr,Port,Dir]).
-get_nof_clients(Mode, Load) ->
- get_nof_clients(test_server:os_type(), Mode, Load).
+block_user(Node,User,Port,Dir,Sec) ->
+ Addr = undefined, % Assumed to be on the same host
+ rpc:call(Node, mod_security, block_user, [User, Addr, Port, Dir, Sec]).
-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.
+unblock_user(Node,User,Port,Dir) ->
+ Addr = undefined, % Assumed to be on the same host
+ rpc:call(Node, mod_security, unblock_user, [User, Addr, Port, Dir]).
-%% 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,
+list_auth_users(Node,Port) ->
+ Addr = undefined, % Assumed to be on the same host
+ rpc:call(Node, mod_security, list_auth_users, [Addr,Port]).
- 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).
+list_auth_users(Node,Port,Dir) ->
+ Addr = undefined, % Assumed to be on the same host
+ rpc:call(Node, mod_security, list_auth_users, [Addr,Port,Dir]).
+
+event(What, Port, Dir, Data) ->
+ Msg = {event, What, Port, Dir, Data},
+ case global:whereis_name(mod_security_test) of
+ undefined ->
+ ok;
+ _Pid ->
+ global:send(mod_security_test, Msg)
+ end.
+type(ip_comm) ->
+ tcp;
+type(_) ->
+ ssl.
+
+typestr(ip_comm) ->
+ "tcp";
+typestr(_) ->
+ "ssl".
+
+response_header({"server", _}) ->
+ false;
+response_header(Header) ->
+ {true, Header}.
+
+response_default_headers() ->
+ [%% Add new header
+ {"X-Frame-Options", "SAMEORIGIN"},
+ %% Override built-in default
+ {"Date", "Override-date"}].
+
+peer(Config) ->
+ case proplists:get_value(type, Config) of
+ ssl ->
+ "true";
+ _ ->
+ "false"
+ end.
diff --git a/lib/inets/test/httpd_SUITE_data/Makefile.src b/lib/inets/test/httpd_SUITE_data/Makefile.src
index b0fdb43d8d..cea40dd8cb 100644
--- a/lib/inets/test/httpd_SUITE_data/Makefile.src
+++ b/lib/inets/test/httpd_SUITE_data/Makefile.src
@@ -10,5 +10,10 @@ all: $(PROGS)
cgi_echo@exe@: cgi_echo@obj@
$(LD) $(CROSSLDFLAGS) -o cgi_echo cgi_echo@obj@ @LIBS@
+@IFEQ@ (@CC@, cl -nologo)
+cgi_echo@obj@: cgi_echo.c
+ $(CC) /c /Focgi_echo@obj@ $(CFLAGS) cgi_echo.c
+@ELSE@
cgi_echo@obj@: cgi_echo.c
$(CC) -c -o cgi_echo@obj@ $(CFLAGS) cgi_echo.c
+@ENDIF@
diff --git a/lib/inets/test/httpd_SUITE_data/mime_types.txt b/lib/inets/test/httpd_SUITE_data/mime_types.txt
new file mode 100644
index 0000000000..3149a119d5
--- /dev/null
+++ b/lib/inets/test/httpd_SUITE_data/mime_types.txt
@@ -0,0 +1,100 @@
+# This is a comment. I love comments.
+
+
+application/activemessage
+application/andrew-inset
+application/applefile
+application/atomicmail
+application/dca-rft
+application/dec-dx
+application/mac-binhex40 hqx
+application/mac-compactpro cpt
+application/macwriteii
+application/msword doc
+application/news-message-id
+application/news-transmission
+application/octet-stream bin dms lha lzh exe class
+application/oda oda
+application/pdf pdf
+application/postscript ai eps ps
+application/powerpoint ppt
+application/remote-printing
+application/rtf rtf
+application/slate
+application/wita
+application/wordperfect5.1
+application/x-bcpio bcpio
+application/x-cdlink vcd
+application/x-compress Z
+application/x-cpio cpio
+application/x-csh csh
+application/x-director dcr dir dxr
+application/x-dvi dvi
+application/x-gtar gtar
+application/x-gzip gz
+application/x-hdf hdf
+application/x-httpd-cgi cgi
+application/x-koan skp skd skt skm
+application/x-latex latex
+application/x-mif mif
+application/x-netcdf nc cdf
+application/x-sh sh
+application/x-shar shar
+application/x-stuffit sit
+application/x-sv4cpio sv4cpio
+application/x-sv4crc sv4crc
+application/x-tar tar
+application/x-tcl tcl
+application/x-tex tex
+application/x-texinfo texinfo texi
+application/x-troff t tr roff
+application/x-troff-man man
+application/x-troff-me me
+application/x-troff-ms ms
+application/x-ustar ustar
+application/x-wais-source src
+application/zip zip
+audio/basic au snd
+audio/mpeg mpga mp2
+audio/x-aiff aif aiff aifc
+audio/x-pn-realaudio ram
+audio/x-pn-realaudio-plugin rpm
+audio/x-realaudio ra
+audio/x-wav wav
+chemical/x-pdb pdb xyz
+image/gif gif
+image/ief ief
+image/jpeg jpeg jpg jpe
+image/png png
+image/tiff tiff tif
+image/x-cmu-raster ras
+image/x-portable-anymap pnm
+image/x-portable-bitmap pbm
+image/x-portable-graymap pgm
+image/x-portable-pixmap ppm
+image/x-rgb rgb
+image/x-xbitmap xbm
+image/x-xpixmap xpm
+image/x-xwindowdump xwd
+message/external-body
+message/news
+message/partial
+message/rfc822
+multipart/alternative
+multipart/appledouble
+multipart/digest
+multipart/mixed
+multipart/parallel
+text/css css
+text/html html htm
+text/plain txt
+text/richtext rtx
+text/tab-separated-values tsv
+text/x-setext etx
+text/x-sgml sgml sgm
+video/mpeg mpeg mpg mpe
+video/quicktime qt mov
+video/x-msvideo avi
+video/x-sgi-movie movie
+x-conference/x-cooltalk ice
+x-world/x-vrml wrl vrml
diff --git a/lib/inets/test/httpd_SUITE_data/server_root/config/mime.types b/lib/inets/test/httpd_SUITE_data/server_root/config/mime.types
new file mode 100644
index 0000000000..b68cff21a6
--- /dev/null
+++ b/lib/inets/test/httpd_SUITE_data/server_root/config/mime.types
@@ -0,0 +1,4 @@
+text/html html
+text/html htm
+text/html shtml
+image/gif gif
diff --git a/lib/inets/test/httpd_SUITE_data/server_root/ssl/ssl_client.pem b/lib/inets/test/httpd_SUITE_data/server_root/ssl/ssl_client.pem
deleted file mode 100644
index 8221139eb4..0000000000
--- a/lib/inets/test/httpd_SUITE_data/server_root/ssl/ssl_client.pem
+++ /dev/null
@@ -1,22 +0,0 @@
------BEGIN RSA PRIVATE KEY-----
-MIIBPAIBAAJBAL6Ym/bgUvhhnPkw08sggGg8Tnp759ThGMEjkmDzhuJ3w3PfnF65
-mgHcgunku4G6LxAQfEUougJWf9Phmjj3oRUCAwEAAQJBAKMjvVvzZxFzfAlP4flc
-OI0AEayFokp04dtvtzuFN09f+aBo2dP18xHmKLCZvxrBOaRAROoQYscALiIVpN07
-GAECIQDfi+sSfAFaDlT3vzpL3xE5UEH6IzY8jWpaZfM1QaToJQIhANpEF50H4wGO
-8Sbh7dUutNd+s+NYUjsMySW2DjLKMsoxAiEAzzb2ftrdsempD0F+O0gZwiPIFKLB
-Kp33YLYyHEKuJtUCIDGi+pvDh2R7VWw6RRQOIyI+tjolg83aAoSI+oGiahqBAiEA
-xzmNNajwoaokvWvlaz0na8rhxu45grOvDrflBT9XvSQ=
------END RSA PRIVATE KEY-----
------BEGIN CERTIFICATE-----
-MIICDDCCAbYCAQAwDQYJKoZIhvcNAQEEBQAwgZAxCzAJBgNVBAYTAlNFMRIwEAYD
-VQQIEwlTdG9ja2hvbG0xDzANBgNVBAcTBkFsdnNqbzEMMAoGA1UEChMDRVRYMQ4w
-DAYDVQQLEwVETi9TUDEXMBUGA1UEAxMOSm9ha2ltIEdyZWJlbm8xJTAjBgkqhkiG
-9w0BCQEWFmpvY2tlQGVyaXguZXJpY3Nzb24uc2UwHhcNOTcwNzE1MTUzNDM2WhcN
-MDMwMjIyMTUzNDM2WjCBkDELMAkGA1UEBhMCU0UxEjAQBgNVBAgTCVN0b2NraG9s
-bTEPMA0GA1UEBxMGQWx2c2pvMQwwCgYDVQQKEwNFVFgxDjAMBgNVBAsTBUROL1NQ
-MRcwFQYDVQQDEw5Kb2FraW0gR3JlYmVubzElMCMGCSqGSIb3DQEJARYWam9ja2VA
-ZXJpeC5lcmljc3Nvbi5zZTBcMA0GCSqGSIb3DQEBAQUAA0sAMEgCQQC+mJv24FL4
-YZz5MNPLIIBoPE56e+fU4RjBI5Jg84bid8Nz35xeuZoB3ILp5LuBui8QEHxFKLoC
-Vn/T4Zo496EVAgMBAAEwDQYJKoZIhvcNAQEEBQADQQBYxQVfTydyZCE0UXvZd7Ei
-josNsAaWJk9fFIJaG9uyXCEfg2dVgoT2eBk3D9DI+7OB+78isM5CVlFbL7hilvP8
------END CERTIFICATE-----
diff --git a/lib/inets/test/httpd_SUITE_data/server_root/ssl/ssl_server.pem b/lib/inets/test/httpd_SUITE_data/server_root/ssl/ssl_server.pem
deleted file mode 100644
index fe739c15f7..0000000000
--- a/lib/inets/test/httpd_SUITE_data/server_root/ssl/ssl_server.pem
+++ /dev/null
@@ -1,22 +0,0 @@
------BEGIN RSA PRIVATE KEY-----
-MIIBOwIBAAJBAL9Bozj3BIjL5Cy8b3rjMT2kPZRychX4wz9bHoIIiKnKo1xXHYjw
-g3N9zWM1f1ZzMADwVry1uAInA8q09+7hL20CAwEAAQJACwu2ao7RozjrV64WXimK
-6X131P/7GMvCMwGHNIlbozqoOqmZcYrbKaF61l+XuwA2QvTo3ywW1Ivxcyr6TeAr
-PQIhAOX+WXT6yiqqwjt08kjBCJyMgfZtdAO6pc/6pKjNWiZfAiEA1OH1iPW/OQe5
-tlQXpiRVdLyneNsPygPRJc4Bdwu3hbMCIQDbI5pA56QxOzqOREOGJsb5wrciAfAE
-jZbnr72sSN2YqQIgAWFpvzagw9Tp/mWzNY+cwkIK7/yzsIKv04fveH8p9IMCIQCr
-td4IiukeUwXmPSvYM4uCE/+J89wEL9qU8Mlc3gDLXA==
------END RSA PRIVATE KEY-----
------BEGIN CERTIFICATE-----
-MIICDDCCAbYCAQAwDQYJKoZIhvcNAQEEBQAwgZAxCzAJBgNVBAYTAlNFMRIwEAYD
-VQQIEwlTdG9ja2hvbG0xDzANBgNVBAcTBkFsdnNqbzEMMAoGA1UEChMDRVRYMQ4w
-DAYDVQQLEwVETi9TUDEXMBUGA1UEAxMOSm9ha2ltIEdyZWJlbm8xJTAjBgkqhkiG
-9w0BCQEWFmpvY2tlQGVyaXguZXJpY3Nzb24uc2UwHhcNOTcwNzE1MTUzMzQxWhcN
-MDMwMjIyMTUzMzQxWjCBkDELMAkGA1UEBhMCU0UxEjAQBgNVBAgTCVN0b2NraG9s
-bTEPMA0GA1UEBxMGQWx2c2pvMQwwCgYDVQQKEwNFVFgxDjAMBgNVBAsTBUROL1NQ
-MRcwFQYDVQQDEw5Kb2FraW0gR3JlYmVubzElMCMGCSqGSIb3DQEJARYWam9ja2VA
-ZXJpeC5lcmljc3Nvbi5zZTBcMA0GCSqGSIb3DQEBAQUAA0sAMEgCQQC/QaM49wSI
-y+QsvG964zE9pD2UcnIV+MM/Wx6CCIipyqNcVx2I8INzfc1jNX9WczAA8Fa8tbgC
-JwPKtPfu4S9tAgMBAAEwDQYJKoZIhvcNAQEEBQADQQAmXDY1CyJjzvQZX442kkHG
-ic9QFY1UuVfzokzNMwlHYl1Qx9zaodx0cJCrcH5GF9O9LJbhhV77LzoxT1Q5wZp5
------END CERTIFICATE-----
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_basic_SUITE.erl b/lib/inets/test/httpd_basic_SUITE.erl
index 523cf9d38c..f413248092 100644
--- a/lib/inets/test/httpd_basic_SUITE.erl
+++ b/lib/inets/test/httpd_basic_SUITE.erl
@@ -1,24 +1,26 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2007-2012. All Rights Reserved.
+%% Copyright Ericsson AB 2007-2016. 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.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
+%%
+%% http://www.apache.org/licenses/LICENSE-2.0
+%%
+%% Unless required by applicable law or agreed to in writing, software
+%% distributed under the License is distributed on an "AS IS" BASIS,
+%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+%% See the License for the specific language governing permissions and
+%% limitations under the License.
%%
%% %CopyrightEnd%
%%
%%
-module(httpd_basic_SUITE).
+-include_lib("kernel/include/file.hrl").
-include_lib("common_test/include/ct.hrl").
-include("inets_test_lib.hrl").
@@ -28,14 +30,19 @@
-define(URL_START, "http://localhost:").
-suite() -> [{ct_hooks,[ts_install_cth]}].
+suite() -> [{ct_hooks,[ts_install_cth]},
+ {timetrap, {seconds, 30}}].
all() ->
- [
- uri_too_long_414,
- header_too_long_413,
+ [uri_too_long_414,
+ header_too_long_413,
+ entity_too_long,
+ erl_script_nocache_opt,
+ script_nocache,
escaped_url_in_error_body,
- slowdose
+ script_timeout,
+ slowdose,
+ keep_alive_timeout
].
groups() ->
@@ -58,13 +65,13 @@ end_per_group(_GroupName, Config) ->
%% variable, but should NOT alter/remove any existing entries.
%%--------------------------------------------------------------------
init_per_suite(Config) ->
- tsp("init_per_suite -> entry with"
- "~n Config: ~p", [Config]),
- ok = inets:start(),
- PrivDir = ?config(priv_dir, Config),
-
+ inets_test_lib:stop_apps([inets]),
+ inets_test_lib:start_apps([inets]),
+ PrivDir = proplists:get_value(priv_dir, Config),
+ DataDir = proplists:get_value(data_dir, Config),
+
Dummy =
-"<HTML>
+ "<HTML>
<HEAD>
<TITLE>/index.html</TITLE>
</HEAD>
@@ -72,8 +79,23 @@ init_per_suite(Config) ->
DUMMY
</BODY>
</HTML>",
-
+
DummyFile = filename:join([PrivDir,"dummy.html"]),
+ CgiDir = filename:join(PrivDir, "cgi-bin"),
+ ok = file:make_dir(CgiDir),
+ {CgiPrintEnv, CgiSleep} = case test_server:os_type() of
+ {win32, _} ->
+ {"printenv.bat", "cgi_sleep.exe"};
+ _ ->
+ {"printenv.sh", "cgi_sleep"}
+ end,
+ lists:foreach(
+ fun(Cgi) ->
+ 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})
+ end, [CgiPrintEnv, CgiSleep]),
{ok, Fd} = file:open(DummyFile, [write]),
ok = file:write(Fd, Dummy),
ok = file:close(Fd),
@@ -84,7 +106,8 @@ DUMMY
{document_root, PrivDir},
{bind_address, "localhost"}],
- [{httpd_conf, HttpdConf} | Config].
+ [{httpd_conf, HttpdConf}, {cgi_dir, CgiDir},
+ {cgi_printenv, CgiPrintEnv}, {cgi_sleep, CgiSleep} | Config].
%%--------------------------------------------------------------------
%% Function: end_per_suite(Config) -> _
@@ -93,8 +116,6 @@ DUMMY
%% Description: Cleanup after the whole suite
%%--------------------------------------------------------------------
end_per_suite(_Config) ->
- tsp("end_per_suite -> entry with"
- "~n Config: ~p", [_Config]),
inets:stop(),
ok.
@@ -110,9 +131,7 @@ end_per_suite(_Config) ->
%% 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) ->
- tsp("init_per_testcase(~w) -> entry with"
- "~n Config: ~p", [Case, Config]),
+init_per_testcase(_Case, Config) ->
Config.
@@ -124,22 +143,18 @@ init_per_testcase(Case, Config) ->
%% A list of key/value pairs, holding the test case configuration.
%% Description: Cleanup after each test case
%%--------------------------------------------------------------------
-end_per_testcase(Case, Config) ->
- tsp("end_per_testcase(~w) -> entry with"
- "~n Config: ~p", [Case, Config]),
+end_per_testcase(_Case, Config) ->
Config.
%%-------------------------------------------------------------------------
%% Test cases starts here.
%%-------------------------------------------------------------------------
-uri_too_long_414(doc) ->
- ["Test that too long uri's get 414 HTTP code"];
-uri_too_long_414(suite) ->
- [];
+uri_too_long_414() ->
+ [{doc, "Test that too long uri's get 414 HTTP code"}].
uri_too_long_414(Config) when is_list(Config) ->
- HttpdConf = ?config(httpd_conf, Config),
- {ok, Pid} = inets:start(httpd, [{port, 0}, {max_uri_size, 10}
+ HttpdConf = proplists:get_value(httpd_conf, Config),
+ {ok, Pid} = inets:start(httpd, [{max_uri_size, 10}
| HttpdConf]),
Info = httpd:info(Pid),
Port = proplists:get_value(port, Info),
@@ -155,17 +170,12 @@ uri_too_long_414(Config) when is_list(Config) ->
{version, "HTTP/0.9"}]),
inets:stop(httpd, Pid).
-
%%-------------------------------------------------------------------------
-%%-------------------------------------------------------------------------
-
-header_too_long_413(doc) ->
- ["Test that too long headers's get 413 HTTP code"];
-header_too_long_413(suite) ->
- [];
+header_too_long_413() ->
+ [{doc,"Test that too long headers's get 413 HTTP code"}].
header_too_long_413(Config) when is_list(Config) ->
- HttpdConf = ?config(httpd_conf, Config),
- {ok, Pid} = inets:start(httpd, [{port, 0}, {max_header_size, 10}
+ HttpdConf = proplists:get_value(httpd_conf, Config),
+ {ok, Pid} = inets:start(httpd, [{max_header_size, 10}
| HttpdConf]),
Info = httpd:info(Pid),
Port = proplists:get_value(port, Info),
@@ -178,111 +188,191 @@ header_too_long_413(Config) when is_list(Config) ->
{version, "HTTP/1.1"}]),
inets:stop(httpd, Pid).
-
%%-------------------------------------------------------------------------
+
+entity_too_long() ->
+ [{doc, "Test that too long versions and method strings are rejected"}].
+entity_too_long(Config) when is_list(Config) ->
+ HttpdConf = proplists:get_value(httpd_conf, Config),
+ {ok, Pid} = inets:start(httpd, HttpdConf),
+ Info = httpd:info(Pid),
+ Port = proplists:get_value(port, Info),
+ Address = proplists:get_value(bind_address, Info),
+
+ %% Not so long but wrong
+ ok = httpd_test_lib:verify_request(ip_comm, Address, Port, node(),
+ "GET / " ++
+ lists:duplicate(5, $A) ++ "\r\n\r\n",
+ [{statuscode, 400},
+ %% Server will send lowest version
+ %% as it will not get to the
+ %% client version
+ %% before aborting
+ {version, "HTTP/0.9"}]),
+
+ %% Too long
+ ok = httpd_test_lib:verify_request(ip_comm, Address, Port, node(),
+ "GET / " ++
+ lists:duplicate(100, $A) ++ "\r\n\r\n",
+ [{statuscode, 413},
+ %% Server will send lowest version
+ %% as it will not get to the
+ %% client version
+ %% before aborting
+ {version, "HTTP/0.9"}]),
+ %% Not so long but wrong
+ ok = httpd_test_lib:verify_request(ip_comm, Address, Port, node(),
+ lists:duplicate(5, $A) ++ " / "
+ "HTTP/1.1\r\n\r\n",
+ [{statuscode, 501},
+ %% Server will send lowest version
+ %% as it will not get to the
+ %% client version
+ %% before aborting
+ {version, "HTTP/1.1"}]),
+ %% Too long
+ ok = httpd_test_lib:verify_request(ip_comm, Address, Port, node(),
+ lists:duplicate(100, $A) ++ " / "
+ "HTTP/1.1\r\n\r\n",
+ [{statuscode, 413},
+ %% Server will send lowest version
+ %% as it will not get to the
+ %% client version
+ %% before aborting
+ {version, "HTTP/0.9"}]),
+ inets:stop(httpd, Pid).
+
%%-------------------------------------------------------------------------
-escaped_url_in_error_body(doc) ->
- ["Test Url-encoding see OTP-8940"];
-escaped_url_in_error_body(suite) ->
+script_nocache() ->
+ [{doc,"Test nocache option for mod_cgi and mod_esi"}].
+script_nocache(Config) when is_list(Config) ->
+ Normal = {no_header, "cache-control"},
+ NoCache = {header, "cache-control", "no-cache"},
+ verify_script_nocache(Config, false, false, Normal, Normal),
+ verify_script_nocache(Config, true, false, NoCache, Normal),
+ verify_script_nocache(Config, false, true, Normal, NoCache),
+ verify_script_nocache(Config, true, true, NoCache, NoCache).
+
+%%-------------------------------------------------------------------------
+erl_script_nocache_opt(doc) ->
+ ["Test that too long headers's get 413 HTTP code"];
+erl_script_nocache_opt(suite) ->
[];
-escaped_url_in_error_body(Config) when is_list(Config) ->
- %% <CONDITIONAL-SKIP>
- %% This skip is due to a problem on windows with long path's
- %% If a path is too long file:open fails with, for example, eio.
- %% Until that problem is fixed, we skip this case...
- Skippable = [win32],
- Condition = fun() -> ?OS_BASED_SKIP(Skippable) end,
- ?NON_PC_TC_MAYBE_SKIP(Config, Condition),
- %% </CONDITIONAL-SKIP>
-
- tsp("escaped_url_in_error_body -> entry"),
- HttpdConf = ?config(httpd_conf, Config),
- {ok, Pid} = inets:start(httpd, [{port, 0} | HttpdConf]),
+erl_script_nocache_opt(Config) when is_list(Config) ->
+ HttpdConf = proplists:get_value(httpd_conf, Config),
+ {ok, Pid} = inets:start(httpd, [{port, 0}, {erl_script_nocache, true} | HttpdConf]),
Info = httpd:info(Pid),
Port = proplists:get_value(port, Info),
_Address = proplists:get_value(bind_address, Info),
-
- %% Request 1
- tss(1000),
- tsp("escaped_url_in_error_body -> request 1"),
URL1 = ?URL_START ++ integer_to_list(Port),
- %% Make sure the server is ok, by making a request for a valid page
case httpc:request(get, {URL1 ++ "/dummy.html", []},
[{url_encode, false},
{version, "HTTP/1.0"}],
[{full_result, false}]) of
{ok, {200, _}} ->
- %% Don't care about the the body, just that we get a ok response
- ok;
- {ok, {StatusCode1, Body1}} ->
- tsf({unexpected_ok_1, StatusCode1, Body1})
+ ok
end,
+ inets:stop(httpd, Pid).
+
+%%-------------------------------------------------------------------------
- %% Request 2
- tss(1000),
- tsp("escaped_url_in_error_body -> request 2"),
- %% Make sure the server is ok, by making a request for a valid page
- case httpc:request(get, {URL1 ++ "/dummy.html", []},
- [{url_encode, true},
- {version, "HTTP/1.0"}],
- [{full_result, false}]) of
- {ok, {200, _}} ->
- %% Don't care about the the body, just that we get a ok response
- ok;
- {ok, {StatusCode2, Body2}} ->
- tsf({unexpected_ok_2, StatusCode2, Body2})
- end,
- %% Request 3
- tss(1000),
- tsp("escaped_url_in_error_body -> request 3"),
+%%-------------------------------------------------------------------------
+
+escaped_url_in_error_body() ->
+ [{doc, "Test Url-encoding see OTP-8940"}].
+escaped_url_in_error_body(Config) when is_list(Config) ->
+ HttpdConf = proplists:get_value(httpd_conf, Config),
+ {ok, Pid} = inets:start(httpd, [{port, 0} | HttpdConf]),
+ Info = httpd:info(Pid),
+ Port = proplists:get_value(port, Info),
+ URL1 = ?URL_START ++ integer_to_list(Port),
+
+ %% Sanity check
+ {ok, {200, _}} = httpc:request(get, {URL1 ++ "/dummy.html", []},
+ [{url_encode, false},
+ {version, "HTTP/1.0"}],
+ [{full_result, false}]),
+ {ok, {200, _}} = httpc:request(get, {URL1 ++ "/dummy.html", []},
+ [{url_encode, true},
+ {version, "HTTP/1.0"}],
+ [{full_result, false}]),
+
%% Ask for a non-existing page(1)
Path = "/<b>this_is_bold<b>",
HTMLEncodedPath = http_util:html_encode(Path),
URL2 = URL1 ++ Path,
- case httpc:request(get, {URL2, []},
- [{url_encode, true},
- {version, "HTTP/1.0"}],
- [{full_result, false}]) of
- {ok, {404, Body3}} ->
- case find_URL_path(string:tokens(Body3, " ")) of
- HTMLEncodedPath ->
- ok;
- BadPath3 ->
- tsf({unexpected_path_3, HTMLEncodedPath, BadPath3})
- end;
- {ok, UnexpectedOK3} ->
- tsf({unexpected_ok_3, UnexpectedOK3})
+ {ok, {404, Body3}} = httpc:request(get, {URL2, []},
+ [{url_encode, true},
+ {version, "HTTP/1.0"}],
+ [{full_result, false}]),
+
+ HTMLEncodedPath = find_URL_path(string:tokens(Body3, " ")),
+
+ {ok, {404, Body4}} = httpc:request(get, {URL2, []},
+ [{url_encode, false},
+ {version, "HTTP/1.0"}],
+ [{full_result, false}]),
+
+ HTMLEncodedPath = find_URL_path(string:tokens(Body4, " ")),
+ inets:stop(httpd, Pid).
+
+%%-------------------------------------------------------------------------
+
+keep_alive_timeout(doc) ->
+ ["Test the keep_alive_timeout option"];
+keep_alive_timeout(suite) ->
+ [];
+keep_alive_timeout(Config) when is_list(Config) ->
+ HttpdConf = proplists:get_value(httpd_conf, Config),
+ {ok, Pid} = inets:start(httpd, [{port, 0}, {keep_alive, true}, {keep_alive_timeout, 2} | HttpdConf]),
+ Info = httpd:info(Pid),
+ Port = proplists:get_value(port, Info),
+ _Address = proplists:get_value(bind_address, Info),
+ {ok, S} = gen_tcp:connect("localhost", Port, []),
+ receive
+ after 3000 ->
+ {error, closed} = gen_tcp:send(S, "hey")
end,
+ inets:stop(httpd, Pid).
- %% Request 4
- tss(1000),
- tsp("escaped_url_in_error_body -> request 4"),
- %% Ask for a non-existing page(2)
- case httpc:request(get, {URL2, []},
- [{url_encode, false},
- {version, "HTTP/1.0"}],
- [{full_result, false}]) of
- {ok, {404, Body4}} ->
- case find_URL_path(string:tokens(Body4, " ")) of
- HTMLEncodedPath ->
- ok;
- BadPath4 ->
- tsf({unexpected_path_4, HTMLEncodedPath, BadPath4})
- end;
- {ok, UnexpectedOK4} ->
- tsf({unexpected_ok_4, UnexpectedOK4})
- end,
- tss(1000),
- tsp("escaped_url_in_error_body -> stop inets"),
- inets:stop(httpd, Pid),
- tsp("escaped_url_in_error_body -> done"),
+%%-------------------------------------------------------------------------
+
+script_timeout(doc) ->
+ ["Test the httpd script_timeout option"];
+script_timeout(suite) ->
+ [];
+script_timeout(Config) when is_list(Config) ->
+ verify_script_timeout(Config, 20, 200),
+ verify_script_timeout(Config, 5, 403),
ok.
-slowdose(doc) ->
- ["Testing minimum bytes per second option"];
+
+verify_script_timeout(Config, ScriptTimeout, StatusCode) ->
+ HttpdConf = proplists:get_value(httpd_conf, Config),
+ CgiScript = proplists:get_value(cgi_sleep, Config),
+ CgiDir = proplists:get_value(cgi_dir, Config),
+ {ok, Pid} = inets:start(httpd, [{port, 0},
+ {script_alias,
+ {"/cgi-bin/", CgiDir ++ "/"}},
+ {script_timeout, ScriptTimeout}
+ | HttpdConf]),
+ Info = httpd:info(Pid),
+ Port = proplists:get_value(port, Info),
+ Address = proplists:get_value(bind_address, Info),
+ ok = httpd_test_lib:verify_request(ip_comm, Address, Port, node(),
+ "GET /cgi-bin/" ++ CgiScript ++
+ " HTTP/1.0\r\n\r\n",
+ [{statuscode, StatusCode},
+ {version, "HTTP/1.0"}]),
+ inets:stop(httpd, Pid).
+
+%%-------------------------------------------------------------------------
+
+slowdose() ->
+ [{doc, "Testing minimum bytes per second option"}].
slowdose(Config) when is_list(Config) ->
- HttpdConf = ?config(httpd_conf, Config),
+ HttpdConf = proplists:get_value(httpd_conf, Config),
{ok, Pid} = inets:start(httpd, [{port, 0}, {minimum_bytes_per_second, 200}|HttpdConf]),
Info = httpd:info(Pid),
Port = proplists:get_value(port, Info),
@@ -291,6 +381,40 @@ slowdose(Config) when is_list(Config) ->
after 6000 ->
{error, closed} = gen_tcp:send(Socket, "Hey")
end.
+
+%%-------------------------------------------------------------------------
+%% Internal functions
+%%-------------------------------------------------------------------------
+
+verify_script_nocache(Config, CgiNoCache, EsiNoCache, CgiOption, EsiOption) ->
+ HttpdConf = proplists:get_value(httpd_conf, Config),
+ CgiScript = proplists:get_value(cgi_printenv, Config),
+ CgiDir = proplists:get_value(cgi_dir, Config),
+ {ok, Pid} = inets:start(httpd, [{port, 0},
+ {script_alias,
+ {"/cgi-bin/", CgiDir ++ "/"}},
+ {script_nocache, CgiNoCache},
+ {erl_script_alias,
+ {"/cgi-bin/erl", [httpd_example,io]}},
+ {erl_script_nocache, EsiNoCache}
+ | HttpdConf]),
+ Info = httpd:info(Pid),
+ Port = proplists:get_value(port, Info),
+ Address = proplists:get_value(bind_address, Info),
+ ok = httpd_test_lib:verify_request(ip_comm, Address, Port, node(),
+ "GET /cgi-bin/" ++ CgiScript ++
+ " HTTP/1.0\r\n\r\n",
+ [{statuscode, 200},
+ CgiOption,
+ {version, "HTTP/1.0"}]),
+ ok = httpd_test_lib:verify_request(ip_comm, Address, Port, node(),
+ "GET /cgi-bin/erl/httpd_example:get "
+ "HTTP/1.0\r\n\r\n",
+ [{statuscode, 200},
+ EsiOption,
+ {version, "HTTP/1.0"}]),
+ inets:stop(httpd, Pid).
+
find_URL_path([]) ->
"";
find_URL_path(["URL", URL | _]) ->
@@ -298,21 +422,6 @@ find_URL_path(["URL", URL | _]) ->
find_URL_path([_ | Rest]) ->
find_URL_path(Rest).
-
-tsp(F) ->
- inets_test_lib:tsp(F).
-tsp(F, A) ->
- inets_test_lib:tsp(F, A).
-
-tsf(Reason) ->
- inets_test_lib:tsf(Reason).
-
-tss(Time) ->
- inets_test_lib:tss(Time).
-
-
-
-
skip(Reason) ->
{skip, Reason}.
diff --git a/lib/inets/test/httpd_basic_SUITE_data/Makefile.src b/lib/inets/test/httpd_basic_SUITE_data/Makefile.src
new file mode 100644
index 0000000000..9da2ed583f
--- /dev/null
+++ b/lib/inets/test/httpd_basic_SUITE_data/Makefile.src
@@ -0,0 +1,14 @@
+CC = @CC@
+LD = @LD@
+CFLAGS = @CFLAGS@ -I@erl_include@ @DEFS@
+CROSSLDFLAGS = @CROSSLDFLAGS@
+
+PROGS = cgi_sleep@exe@
+
+all: $(PROGS)
+
+cgi_sleep@exe@: cgi_sleep@obj@
+ $(LD) $(CROSSLDFLAGS) -o cgi_sleep cgi_sleep@obj@ @LIBS@
+
+cgi_sleep@obj@: cgi_sleep.c
+ $(CC) -c -o cgi_sleep@obj@ $(CFLAGS) cgi_sleep.c
diff --git a/lib/inets/test/httpd_basic_SUITE_data/cgi_sleep.c b/lib/inets/test/httpd_basic_SUITE_data/cgi_sleep.c
new file mode 100644
index 0000000000..126bb23987
--- /dev/null
+++ b/lib/inets/test/httpd_basic_SUITE_data/cgi_sleep.c
@@ -0,0 +1,26 @@
+#include <stdlib.h>
+#include <stdio.h>
+
+#ifdef __WIN32__
+#include <windows.h>
+#include <fcntl.h>
+#include <io.h>
+#else
+#include <unistd.h>
+#endif
+
+int main(void)
+{
+ unsigned int seconds = 10;
+
+#ifdef __WIN32__
+ Sleep(seconds * 1000);
+ _setmode(_fileno(stdout), _O_BINARY);
+#else
+ sleep(seconds);
+#endif
+
+ printf("Content-type: text/plain\r\n\r\n");
+ printf("Slept for %u seconds.\r\n", seconds);
+ exit(EXIT_SUCCESS);
+}
diff --git a/lib/inets/test/httpd_basic_SUITE_data/printenv.bat b/lib/inets/test/httpd_basic_SUITE_data/printenv.bat
new file mode 120000
index 0000000000..1bc8e52059
--- /dev/null
+++ b/lib/inets/test/httpd_basic_SUITE_data/printenv.bat
@@ -0,0 +1 @@
+../httpd_SUITE_data/server_root/cgi-bin/printenv.bat \ No newline at end of file
diff --git a/lib/inets/test/httpd_basic_SUITE_data/printenv.sh b/lib/inets/test/httpd_basic_SUITE_data/printenv.sh
new file mode 120000
index 0000000000..0136a3fa23
--- /dev/null
+++ b/lib/inets/test/httpd_basic_SUITE_data/printenv.sh
@@ -0,0 +1 @@
+../httpd_SUITE_data/server_root/cgi-bin/printenv.sh \ No newline at end of file
diff --git a/lib/inets/test/httpd_block.erl b/lib/inets/test/httpd_block.erl
index ac1bf43ff5..45547e6d4e 100644
--- a/lib/inets/test/httpd_block.erl
+++ b/lib/inets/test/httpd_block.erl
@@ -1,26 +1,26 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2005-2010. All Rights Reserved.
+%% Copyright Ericsson AB 2005-2016. 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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% 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.
+%% http://www.apache.org/licenses/LICENSE-2.0
+%%
+%% Unless required by applicable law or agreed to in writing, software
+%% distributed under the License is distributed on an "AS IS" BASIS,
+%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+%% See the License for the specific language governing permissions and
+%% limitations under the License.
%%
%% %CopyrightEnd%
%%
%%
-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 +88,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 +100,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,9 +111,8 @@ 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),
- Blocker = blocker(Node, Host, Port, 50000),
- await_normal_process_exit(Blocker, "blocker", 50000),
+ ct:sleep(15000),
+ ok = httpd_block(undefined, Port, disturbing, 50000),
await_normal_process_exit(Poller, "poller", 30000),
blocked = get_admin_state(Node, Host, Port),
process_flag(trap_exit, false),
@@ -123,9 +122,8 @@ 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),
- Blocker = blocker(Node, Host, Port, 10000),
- await_normal_process_exit(Blocker, "blocker", 15000),
+ ct:sleep(5000),
+ ok = httpd_block(undefined, Port, disturbing, 10000),
await_suite_failed_process_exit(Poller, "poller", 40000,
connection_closed),
blocked = get_admin_state(Node, Host, Port),
@@ -135,7 +133,7 @@ block_disturbing_active_timeout_released(Type, Port, Host, Node) ->
block_non_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(5000),
+ ct:sleep(5000),
ok = block_nd_server(Node, Host, Port, 40000),
await_normal_process_exit(Poller, "poller", 60000),
blocked = get_admin_state(Node, Host, Port),
@@ -146,7 +144,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 +155,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 +168,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),
@@ -295,11 +293,14 @@ httpd_restart(Addr, Port) ->
end.
make_name(Addr, Port) ->
- httpd_util:make_name("httpd", Addr, Port).
+ httpd_util:make_name("httpd", Addr, Port, default).
-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 +324,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 +340,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 +360,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_load.erl b/lib/inets/test/httpd_load.erl
index 83520033dc..7f4d16139f 100644
--- a/lib/inets/test/httpd_load.erl
+++ b/lib/inets/test/httpd_load.erl
@@ -1,18 +1,19 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2005-2010. All Rights Reserved.
+%% Copyright Ericsson AB 2005-2016. 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.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
+%%
+%% http://www.apache.org/licenses/LICENSE-2.0
+%%
+%% Unless required by applicable law or agreed to in writing, software
+%% distributed under the License is distributed on an "AS IS" BASIS,
+%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+%% See the License for the specific language governing permissions and
+%% limitations under the License.
%%
%% %CopyrightEnd%
%%
@@ -20,8 +21,7 @@
-module(httpd_load).
--include("test_server.hrl").
--include("test_server_line.hrl").
+-include_lib("common_test/include/ct.hrl").
%% General testcases bodies called from httpd_SUITE
-export([load_test/5]).
@@ -63,7 +63,7 @@ load_test(Fun, URIs, Type, Host, Port, Node, 0, List) ->
{'EXIT', Pid, Reason} ->
Str = lists:flatten(io_lib:format("client ~p exited: ~p",
[Pid,Reason])),
- test_server:fail(Str);
+ ct:fail(Str);
_ ->
load_test(Fun, URIs, Type, Host, Port, Node, 0, List)
end;
@@ -86,12 +86,11 @@ load_test_client(Fun, [URI|URIs], Type, Host, Port, Node, Boss, Timeout) ->
{'EXIT', {suite_failed, connection_closed, _, _}} ->
%% Some platforms seems to handle heavy load badly.
%% So, back off and see if this helps
- %%?LOG("load_test_client->requestfailed:connection_closed"[]),
2 * Timeout;
_ ->
Timeout
end,
- test_server:sleep(Timeout1),
+ ct:sleep(Timeout1),
load_test_client(Fun, URIs, Type, Host, Port, Node, Boss, Timeout1).
load_test_client_done(Boss) ->
diff --git a/lib/inets/test/httpd_mod.erl b/lib/inets/test/httpd_mod.erl
index df4ed6b179..d9118aa1a4 100644
--- a/lib/inets/test/httpd_mod.erl
+++ b/lib/inets/test/httpd_mod.erl
@@ -1,18 +1,19 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2005-2013. All Rights Reserved.
+%% Copyright Ericsson AB 2005-2016. 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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% 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.
+%% http://www.apache.org/licenses/LICENSE-2.0
+%%
+%% Unless required by applicable law or agreed to in writing, software
+%% distributed under the License is distributed on an "AS IS" BASIS,
+%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+%% See the License for the specific language governing permissions and
+%% limitations under the License.
%%
%% %CopyrightEnd%
%%
@@ -20,8 +21,7 @@
-module(httpd_mod).
--include("test_server.hrl").
--include("test_server_line.hrl").
+-include_lib("common_test/include/ct.hrl").
%% General testcases bodies called from httpd_SUITE
-export([alias/4, actions/4, security/5, auth/4, auth_api/6,
@@ -86,240 +86,116 @@ actions(Type, Port, Host, Node) ->
security(ServerRoot, Type, Port, Host, Node) ->
global:register_name(mod_security_test, self()), % Receive events
-
- tsp("security -> "
- "sleep"),
- test_server:sleep(5000),
+
+ ct:sleep(5000),
OpenDir = filename:join([ServerRoot, "htdocs", "open"]),
%% Test blocking / unblocking of users.
%% /open, require user one Aladdin
- tsp("security -> "
- "blocking and unblocking of users - "
- "remove all existing users"),
+
remove_users(Node, ServerRoot, Host, Port, "open"),
- tsp("security -> "
- "blocking and unblocking of users - "
- "auth request for nonex user 'one' - expect 401"),
auth_request(Type, Host, Port, Node, "/open/", "one", "onePassword",
[{statuscode, 401}]),
- tsp("security -> "
- "blocking and unblocking of users - "
- "await fail security event"),
receive_security_event({event, auth_fail, Port, OpenDir,
[{user, "one"}, {password, "onePassword"}]},
Node, Port),
- tsp("security -> "
- "blocking and unblocking of users - "
- "auth request for nonex user 'two' - expect 401"),
auth_request(Type,Host,Port,Node,"/open/", "two", "twoPassword",
[{statuscode, 401}]),
- tsp("security -> "
- "blocking and unblocking of users - "
- "await fail security event"),
receive_security_event({event, auth_fail, Port, OpenDir,
[{user, "two"}, {password, "twoPassword"}]},
Node, Port),
-
- tsp("security -> "
- "blocking and unblocking of users - "
- "auth request for nonex user 'Alladin' - expect 401"),
auth_request(Type, Host, Port, Node,"/open/", "Aladdin",
"AladdinPassword", [{statuscode, 401}]),
- tsp("security -> "
- "blocking and unblocking of users - "
- "await fail security event"),
receive_security_event({event, auth_fail, Port, OpenDir,
[{user, "Aladdin"},
{password, "AladdinPassword"}]},
Node, Port),
-
- tsp("security -> "
- "blocking and unblocking of users - "
- "add user 'one'"),
add_user(Node, ServerRoot, Port, "open", "one", "onePassword", []),
- tsp("security -> "
- "blocking and unblocking of users - "
- "add user 'two'"),
add_user(Node, ServerRoot, Port, "open", "two", "twoPassword", []),
- tsp("security -> "
- "blocking and unblocking of users - "
- "auth request 1 for user 'one' with wrong password - expect 401"),
auth_request(Type, Host, Port, Node,"/open/", "one", "WrongPassword",
[{statuscode, 401}]),
-
- tsp("security -> "
- "blocking and unblocking of users - "
- "await fail security event"),
receive_security_event({event, auth_fail, Port, OpenDir,
[{user, "one"}, {password, "WrongPassword"}]},
Node, Port),
-
- tsp("security -> "
- "blocking and unblocking of users - "
- "auth request 2 for user 'one' with wrong password - expect 401"),
auth_request(Type, Host, Port, Node,"/open/", "one", "WrongPassword",
[{statuscode, 401}]),
- tsp("security -> "
- "blocking and unblocking of users - "
- "await fail security event"),
receive_security_event({event, auth_fail, Port, OpenDir,
[{user, "one"}, {password, "WrongPassword"}]},
Node, Port),
-
- tsp("security -> "
- "blocking and unblocking of users - "
- "await block security event (two failed attempts)"),
- receive_security_event({event, user_block, Port, OpenDir,
+ receive_security_event({event, user_block, Port, OpenDir,
[{user, "one"}]}, Node, Port),
- tsp("security -> "
- "blocking and unblocking of users - "
- "unregister - no more security events"),
global:unregister_name(mod_security_test), % No more events.
- tsp("security -> "
- "blocking and unblocking of users - "
- "auth request for user 'one' with wrong password - expect 401"),
auth_request(Type, Host, Port, Node,"/open/", "one", "WrongPassword",
[{statuscode, 401}]),
- tsp("security -> "
- "blocking and unblocking of users - "
- "auth request for user 'one' with correct password - expect 403"),
auth_request(Type, Host, Port, Node,"/open/", "one", "onePassword",
[{statuscode, 403}]),
%% User "one" should be blocked now..
- tsp("security -> "
- "blocking and unblocking of users - "
- "list blocked users - 'one' should be the only one"),
case list_blocked_users(Node, Port) of
[{"one",_, Port, OpenDir,_}] ->
ok;
Blocked ->
- tsp(" *** unexpected blocked users ***"
- "~n Blocked: ~p", [Blocked]),
exit({unexpected_blocked, Blocked})
end,
- tsp("security -> "
- "blocking and unblocking of users - "
- "list users blocked for dir '~p' - "
- "user 'one' should be the only one", [OpenDir]),
[{"one",_, Port, OpenDir,_}] = list_blocked_users(Node, Port, OpenDir),
- tsp("security -> "
- "blocking and unblocking of users - "
- "unblock user 'one' for dir '~p'", [OpenDir]),
true = unblock_user(Node, "one", Port, OpenDir),
%% User "one" should not be blocked any more.
- tsp("security -> "
- "blocking and unblocking of users - "
- "ensure user 'one' is no longer blocked"),
[] = list_blocked_users(Node, Port),
-
- tsp("security -> "
- "blocking and unblocking of users - "
- "auth request for user 'one' with correct password - expect 200"),
auth_request(Type, Host, Port, Node,"/open/", "one", "onePassword",
[{statuscode, 200}]),
%% Test list_auth_users & auth_timeout
-
- tsp("security -> "
- "list-auth-users and auth-timeout - "
- "list auth users - expect user 'one'"),
["one"] = list_auth_users(Node, Port),
- tsp("security -> "
- "list-auth-users and auth-timeout - "
- "auth request for user 'two' with wrong password - expect 401"),
auth_request(Type, Host, Port, Node,"/open/", "two", "onePassword",
[{statuscode, 401}]),
-
- tsp("security -> "
- "list-auth-users and auth-timeout - "
- "list auth users - expect user 'one'"),
["one"] = list_auth_users(Node, Port),
- tsp("security -> "
- "list-auth-users and auth-timeout - "
- "list auth users for dir '~p' - expect user 'one'", [OpenDir]),
["one"] = list_auth_users(Node, Port, OpenDir),
- tsp("security -> "
- "list-auth-users and auth-timeout - "
- "auth request for user 'two' with correct password - expect 401"),
auth_request(Type, Host, Port, Node,"/open/", "two", "twoPassword",
[{statuscode, 401}]),
- tsp("security -> "
- "list-auth-users and auth-timeout - "
- "list auth users - expect user 'one'"),
["one"] = list_auth_users(Node, Port),
- tsp("security -> "
- "list-auth-users and auth-timeout - "
- "list auth users for dir '~p' - expect user 'one'", [OpenDir]),
["one"] = list_auth_users(Node, Port, OpenDir),
%% Wait for successful auth to timeout.
- tsp("security -> "
- "list-auth-users and auth-timeout - "
- "wait for successful auth to timeout"),
- test_server:sleep(?AUTH_TIMEOUT*1001),
-
- tsp("security -> "
- "list-auth-users and auth-timeout - "
- "list auth users - expect none"),
+ ct:sleep(?AUTH_TIMEOUT*1001),
+
[] = list_auth_users(Node, Port),
- tsp("security -> "
- "list-auth-users and auth-timeout - "
- "list auth users for dir '~p'~n - expect none", [OpenDir]),
+
[] = list_auth_users(Node, Port, OpenDir),
%% "two" is blocked.
- tsp("security -> "
- "list-auth-users and auth-timeout - "
- "unblock user 'two' for dir '~p'", [OpenDir]),
true = unblock_user(Node, "two", Port, OpenDir),
-
-
%% Test explicit blocking. Block user 'two'.
- tsp("security -> "
- "explicit blocking - list blocked users - should be none"),
[] = list_blocked_users(Node,Port,OpenDir),
- tsp("security -> "
- "explicit blocking - "
- "block user 'two' for dir '~p'", [OpenDir]),
true = block_user(Node, "two", Port, OpenDir, 10),
-
- tsp("security -> "
- "explicit blocking - "
- "auth request for user 'two' with correct password - expect 401"),
auth_request(Type, Host, Port, Node,"/open/", "two", "twoPassword",
- [{statuscode, 401}]),
- tsp("security -> "
- "done").
-
+ [{statuscode, 401}]).
%%-------------------------------------------------------------------------
auth(Type, Port, Host, Node) ->
@@ -743,7 +619,6 @@ cgi(Type, Port, Host, Node) ->
end,
%% The length (> 100) is intentional
-%% tsp("cgi -> request 01 with length > 100"),
ok = httpd_test_lib:
verify_request(Type, Host, Port, Node,
"POST /cgi-bin/" ++ Script3 ++
@@ -771,55 +646,51 @@ cgi(Type, Port, Host, Node) ->
{version, "HTTP/1.0"},
{header, "content-type", "text/plain"}]),
-%% tsp("cgi -> request 02"),
ok = httpd_test_lib:verify_request(Type, Host, Port, Node,
"GET /cgi-bin/"++ Script ++
" HTTP/1.0\r\n\r\n",
[{statuscode, 200},
{version, "HTTP/1.0"}]),
-%% tsp("cgi -> request 03"),
+
ok = httpd_test_lib:verify_request(Type, Host, Port, Node,
"GET /cgi-bin/not_there "
"HTTP/1.0\r\n\r\n",
[{statuscode, 404},{statuscode, 500},
{version, "HTTP/1.0"}]),
-%% tsp("cgi -> request 04"),
+
ok = httpd_test_lib:verify_request(Type, Host, Port, Node,
"GET /cgi-bin/"++ Script ++
"?Nisse:kkk?sss/lll HTTP/1.0\r\n\r\n",
[{statuscode, 200},
{version, "HTTP/1.0"}]),
-%% tsp("cgi -> request 04"),
+
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"}]),
-%% tsp("cgi -> request 05"),
+
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"}]),
-%% tsp("cgi -> request 06"),
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"}]),
-%% tsp("cgi -> request 07"),
+
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"}]),
-%% tsp("cgi -> request 08"),
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"}]),
-%% tsp("cgi -> request 09"),
ok = httpd_test_lib:verify_request(Type, Host, Port, Node,
"POST /htbin/"++ Script ++
" HTTP/1.0\r\n\r\n",
@@ -827,23 +698,25 @@ cgi(Type, Port, Host, Node) ->
{version, "HTTP/1.0"}]),
%% Execute an existing, but bad CGI script..
-%% tsp("cgi -> request 10 - bad 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"}]),
-%% tsp("cgi -> request 11 - bad script"),
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"}]),
-%% tsp("cgi -> done"),
- ok.
-
+ %% 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"}]).
%%--------------------------------------------------------------------
esi(Type, Port, Host, Node) ->
@@ -899,6 +772,13 @@ esi(Type, Port, Host, Node) ->
" HTTP/1.0\r\n\r\n",
[{statuscode, 302},
{version, "HTTP/1.0"}]),
+ %% Check "ErlScriptNoCache" directive (default: false)
+ ok = httpd_test_lib:verify_request(Type, Host, Port, Node,
+ "GET /cgi-bin/erl/httpd_example:get"
+ " HTTP/1.0\r\n\r\n",
+ [{statuscode, 200},
+ {no_header, "cache-control"},
+ {version, "HTTP/1.0"}]),
ok.
@@ -1003,18 +883,15 @@ list_users(Node, Root, _Host, Port, Dir) ->
receive_security_event(Event, Node, Port) ->
- tsp("receive_security_event -> await ~w event", [element(2, Event)]),
receive
Event ->
- tsp("receive_security_event -> "
- "received expected ~w event", [element(2, Event)]),
ok;
{'EXIT', _, _} ->
receive_security_event(Event, Node, Port)
after 5000 ->
%% Flush the message queue, to see if we got something...
Msgs = inets_test_lib:flush(),
- tsf({expected_event_not_received, Msgs})
+ ct:fail({expected_event_not_received, Msgs})
end.
@@ -1030,10 +907,10 @@ receive_security_event(Event, Node, Port) ->
%% {'EXIT', _, _} ->
%% receive_security_event(Event, Node, Port);
%% Other ->
-%% test_server:fail({unexpected_event,
+%% ct:fail({unexpected_event,
%% {expected, Event}, {received, Other}})
%% after 5000 ->
-%% test_server:fail(no_event_recived)
+%% ct:fail(no_event_recived)
%% end.
@@ -1115,17 +992,4 @@ check_lists_members1(L1,L2) ->
{error,{lists_not_equal,L1,L2}}.
-%% p(F) ->
-%% p(F, []).
-
-%% p(F, A) ->
-%% io:format(user, "~w:" ++ F ++ "~n", [?MODULE|A]).
-
-tsp(F) ->
- inets_test_lib:tsp(F).
-tsp(F, A) ->
- inets_test_lib:tsp(F, A).
-
-tsf(Reason) ->
- test_server:fail(Reason).
diff --git a/lib/inets/test/httpd_mod_SUITE.erl b/lib/inets/test/httpd_mod_SUITE.erl
new file mode 100644
index 0000000000..5ec4e0856d
--- /dev/null
+++ b/lib/inets/test/httpd_mod_SUITE.erl
@@ -0,0 +1,77 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2013-2016. All Rights Reserved.
+%%
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
+%%
+%% http://www.apache.org/licenses/LICENSE-2.0
+%%
+%% Unless required by applicable law or agreed to in writing, software
+%% distributed under the License is distributed on an "AS IS" BASIS,
+%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+%% See the License for the specific language governing permissions 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_poll.erl b/lib/inets/test/httpd_poll.erl
index 32335cabcf..f86e3a979b 100644
--- a/lib/inets/test/httpd_poll.erl
+++ b/lib/inets/test/httpd_poll.erl
@@ -1,18 +1,19 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2000-2010. All Rights Reserved.
+%% Copyright Ericsson AB 2000-2016. 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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% 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.
+%% http://www.apache.org/licenses/LICENSE-2.0
+%%
+%% Unless required by applicable law or agreed to in writing, software
+%% distributed under the License is distributed on an "AS IS" BASIS,
+%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+%% See the License for the specific language governing permissions and
+%% limitations under the License.
%%
%% %CopyrightEnd%
%%
@@ -258,11 +259,11 @@ validate(ExpStatusCode,Socket,Response) ->
vtrace("validate -> Entry with ~p bytes response",[Sz]),
Size = trash_the_rest(Socket,Sz),
close(Socket),
- case inets_regexp:split(Response," ") of
- {ok,["HTTP/1.0",ExpStatusCode|_]} ->
+ case re:split(Response," ", [{return, list}]) of
+ ["HTTP/1.0",ExpStatusCode|_] ->
vlog("response (~p bytes) was ok",[Size]),
ok;
- {ok,["HTTP/1.0",StatusCode|_]} ->
+ ["HTTP/1.0",StatusCode|_] ->
verror("unexpected response status received: ~s => ~s",
[StatusCode,status_to_message(StatusCode)]),
log("unexpected result to GET of '~s': ~s => ~s",
diff --git a/lib/inets/test/httpd_test_data/server_root/Makefile b/lib/inets/test/httpd_test_data/server_root/Makefile
index d7a3231068..ed4d63a3bb 100644
--- a/lib/inets/test/httpd_test_data/server_root/Makefile
+++ b/lib/inets/test/httpd_test_data/server_root/Makefile
@@ -1,18 +1,19 @@
#
# %CopyrightBegin%
#
-# Copyright Ericsson AB 1997-2010. All Rights Reserved.
+# Copyright Ericsson AB 1997-2016. 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/.
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
#
-# 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.
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
#
# %CopyrightEnd%
#
diff --git a/lib/inets/test/httpd_test_data/server_root/conf/8080.conf b/lib/inets/test/httpd_test_data/server_root/conf/8080.conf
index 48e66f0114..7b1b4a15b2 100644
--- a/lib/inets/test/httpd_test_data/server_root/conf/8080.conf
+++ b/lib/inets/test/httpd_test_data/server_root/conf/8080.conf
@@ -1,7 +1,7 @@
Port 8080
#ServerName your.server.net
SocketType ip_comm
-Modules mod_alias mod_auth mod_esi mod_actions mod_cgi mod_include mod_dir mod_get mod_head mod_log mod_disk_log
+Modules mod_alias mod_auth mod_esi mod_actions mod_cgi mod_dir mod_get mod_head mod_log mod_disk_log
ServerAdmin [email protected]
ServerRoot /var/tmp/server_root
ErrorLog logs/error_log_8080
diff --git a/lib/inets/test/httpd_test_data/server_root/conf/8888.conf b/lib/inets/test/httpd_test_data/server_root/conf/8888.conf
index 79bb7fcca4..042779fcd0 100644
--- a/lib/inets/test/httpd_test_data/server_root/conf/8888.conf
+++ b/lib/inets/test/httpd_test_data/server_root/conf/8888.conf
@@ -1,7 +1,7 @@
Port 8888
#ServerName your.server.net
SocketType ip_comm
-Modules mod_alias mod_auth mod_esi mod_actions mod_cgi mod_include mod_dir mod_get mod_head mod_log mod_disk_log
+Modules mod_alias mod_auth mod_esi mod_actions mod_cgi mod_dir mod_get mod_head mod_log mod_disk_log
ServerAdmin [email protected]
ServerRoot /var/tmp/server_root
ErrorLog logs/error_log_8888
diff --git a/lib/inets/test/httpd_test_data/server_root/conf/httpd.conf b/lib/inets/test/httpd_test_data/server_root/conf/httpd.conf
index ceb94237d2..3f9fde03b5 100644
--- a/lib/inets/test/httpd_test_data/server_root/conf/httpd.conf
+++ b/lib/inets/test/httpd_test_data/server_root/conf/httpd.conf
@@ -1,18 +1,19 @@
#
# %CopyrightBegin%
#
-# Copyright Ericsson AB 1997-2011. All Rights Reserved.
+# Copyright Ericsson AB 1997-2016. 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.
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
#
# %CopyrightEnd%
#
@@ -63,7 +64,7 @@ SocketType ip_comm
# WARNING! Do not tamper with this directive unless you are familiar with
# EWSAPI.
-Modules mod_alias mod_auth mod_esi mod_actions mod_cgi mod_responsecontrol mod_trace mod_range mod_head mod_include mod_dir mod_get mod_log mod_disk_log
+Modules mod_alias mod_auth mod_esi mod_actions mod_cgi mod_responsecontrol mod_trace mod_range mod_head mod_dir mod_get mod_log mod_disk_log
# ServerAdmin: Your address, where problems with the server should be
# e-mailed.
diff --git a/lib/inets/test/httpd_test_data/server_root/conf/ssl.conf b/lib/inets/test/httpd_test_data/server_root/conf/ssl.conf
index 8b8c57a98b..de49ceafd0 100644
--- a/lib/inets/test/httpd_test_data/server_root/conf/ssl.conf
+++ b/lib/inets/test/httpd_test_data/server_root/conf/ssl.conf
@@ -1,7 +1,7 @@
Port 8088
#ServerName your.server.net
SocketType ssl
-Modules mod_alias mod_auth mod_esi mod_actions mod_cgi mod_include mod_dir mod_get mod_head mod_log mod_disk_log
+Modules mod_alias mod_auth mod_esi mod_actions mod_cgi mod_dir mod_get mod_head mod_log mod_disk_log
ServerAdmin [email protected]
ServerRoot /var/tmp/server_root
ErrorLog logs/error_log_8088
diff --git a/lib/inets/test/httpd_test_lib.erl b/lib/inets/test/httpd_test_lib.erl
index 13584c50f6..1cecd2642c 100644
--- a/lib/inets/test/httpd_test_lib.erl
+++ b/lib/inets/test/httpd_test_lib.erl
@@ -1,18 +1,19 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2001-2013. All Rights Reserved.
+%% Copyright Ericsson AB 2001-2016. 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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% 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.
+%% http://www.apache.org/licenses/LICENSE-2.0
+%%
+%% Unless required by applicable law or agreed to in writing, software
+%% distributed under the License is distributed on an "AS IS" BASIS,
+%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+%% See the License for the specific language governing permissions and
+%% limitations under the License.
%%
%% %CopyrightEnd%
%%
@@ -91,73 +92,38 @@ verify_request(SocketType, Host, Port, Node, RequestStr, Options, TimeOut)
when (is_integer(TimeOut) orelse (TimeOut =:= infinity)) ->
verify_request(SocketType, Host, Port, [], Node, RequestStr, Options, TimeOut).
-verify_request(SocketType, Host, Port, TranspOpts0, Node, RequestStr, Options, TimeOut) ->
- tsp("verify_request -> entry with"
- "~n SocketType: ~p"
- "~n Host: ~p"
- "~n Port: ~p"
- "~n TranspOpts: ~p"
- "~n Node: ~p"
- "~n Options: ~p"
- "~n TimeOut: ~p",
- [SocketType, Host, Port, TranspOpts0, Node, Options, TimeOut]),
-
- %% For now, until we modernize the httpd tests
- TranspOpts =
- case lists:member(inet6, TranspOpts0) of
- true ->
- TranspOpts0;
- false ->
- [inet | TranspOpts0]
- end,
-
+verify_request(SocketType, Host, Port, TranspOpts, Node, RequestStr, Options, TimeOut) ->
try inets_test_lib:connect_bin(SocketType, Host, Port, TranspOpts) of
{ok, Socket} ->
- tsp("verify_request -> connected - now send message"),
- SendRes = inets_test_lib:send(SocketType, Socket, RequestStr),
- tsp("verify_request -> send result: "
- "~n ~p", [SendRes]),
- State = case inets_regexp:match(RequestStr, "printenv") of
+ ok = inets_test_lib:send(SocketType, Socket, RequestStr),
+ State = case re:run(RequestStr, "printenv", [{capture, none}]) of
nomatch ->
#state{};
- _ ->
+ match ->
#state{print = true}
end,
case request(State#state{request = RequestStr,
socket = Socket}, TimeOut) of
{error, Reason} ->
- tsp("verify_request -> request failed: "
- "~n Reason: ~p", [Reason]),
{error, Reason};
NewState ->
- tsp("verify_request -> validate reply: "
- "~n NewState: ~p", [NewState]),
ValidateResult =
validate(RequestStr, NewState, Options, Node, Port),
- tsp("verify_request -> validation result: "
- "~n ~p", [ValidateResult]),
inets_test_lib:close(SocketType, Socket),
ValidateResult
end;
ConnectError ->
- tsp("verify_request -> connect error: "
- "~n ~p"
- "~n", [ConnectError]),
- tsf({connect_error, ConnectError,
- [SocketType, Host, Port, TranspOpts]})
+ ct:fail({connect_error, ConnectError,
+ [SocketType, Host, Port, TranspOpts]})
catch
T:E ->
- tsp("verify_request -> connect failed: "
- "~n E: ~p"
- "~n T: ~p"
- "~n", [E, T]),
- tsf({connect_failure,
- [{type, T},
- {error, E},
- {stacktrace, erlang:get_stacktrace()},
- {args, [SocketType, Host, Port, TranspOpts]}]})
+ ct:fail({connect_failure,
+ [{type, T},
+ {error, E},
+ {stacktrace, erlang:get_stacktrace()},
+ {args, [SocketType, Host, Port, TranspOpts]}]})
end.
request(#state{mfa = {Module, Function, Args},
@@ -166,10 +132,6 @@ request(#state{mfa = {Module, Function, Args},
HeadRequest = lists:sublist(RequestStr, 1, 4),
receive
{tcp, Socket, Data} ->
- io:format("~p ~w[~w]request -> received (tcp) data"
- "~n Data: ~p"
- "~n", [self(), ?MODULE, ?LINE, Data]),
- print(tcp, Data, State),
case Module:Function([Data | Args]) of
{ok, Parsed} ->
handle_http_msg(Parsed, State);
@@ -179,22 +141,12 @@ request(#state{mfa = {Module, Function, Args},
request(State#state{mfa = NewMFA}, TimeOut)
end;
{tcp_closed, Socket} when Function =:= whole_body ->
- io:format("~p ~w[~w]request -> "
- "received (tcp) closed when whole_body"
- "~n", [self(), ?MODULE, ?LINE]),
- print(tcp, "closed", State),
State#state{body = hd(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
{ok, Parsed} ->
handle_http_msg(Parsed, State);
@@ -204,28 +156,19 @@ request(#state{mfa = {Module, Function, Args},
request(State#state{mfa = NewMFA}, TimeOut)
end;
{ssl_closed, Socket} when Function =:= whole_body ->
- 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:pal("~p ~w[~w]request -> timeout"
+ "~n", [self(), ?MODULE, ?LINE]),
+ ct:fail(connection_timed_out)
end.
handle_http_msg({Version, StatusCode, ReasonPharse, Headers, Body},
State = #state{request = RequestStr}) ->
- io:format("~p ~w[~w]handle_http_msg -> entry with"
- "~n Version: ~p"
- "~n StatusCode: ~p"
- "~n ReasonPharse: ~p"
- "~n Headers: ~p"
- "~n Body: ~p"
- "~n", [self(), ?MODULE, ?LINE,
- Version, StatusCode, ReasonPharse, Headers, Body]),
case is_expect(RequestStr) of
true ->
State#state{status_line = {Version,
@@ -277,7 +220,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.
@@ -285,11 +228,6 @@ validate(RequestStr, #state{status_line = {Version, StatusCode, _},
headers = Headers,
body = Body}, Options, N, P) ->
- tsp("validate -> entry with"
- "~n StatusCode: ~p"
- "~n Headers: ~p"
- "~n Body: ~p", [StatusCode, Headers, Body]),
-
check_version(Version, Options),
case lists:keysearch(statuscode, 1, Options) of
{value, _} ->
@@ -297,11 +235,17 @@ validate(RequestStr, #state{status_line = {Version, StatusCode, _},
_ ->
ok
end,
- do_validate(http_response:header_list(Headers), Options, N, P),
- check_body(RequestStr, StatusCode,
- Headers#http_response_h.'content-type',
- list_to_integer(Headers#http_response_h.'content-length'),
- Body).
+ HList = http_response:header_list(Headers),
+ do_validate(HList, Options, N, P),
+ case lists:keysearch("warning", 1, HList) of
+ {value, _} ->
+ ok;
+ _ ->
+ check_body(RequestStr, StatusCode,
+ Headers#http_response_h.'content-type',
+ list_to_integer(Headers#http_response_h.'content-length'),
+ Body)
+ end.
%--------------------------------------------------------------------
%% Internal functions
@@ -311,20 +255,20 @@ check_version(Version, Options) ->
{value, {version, Version}} ->
ok;
{value, {version, Ver}} ->
- tsf({wrong_version, [{got, Version},
- {expected, Ver}]});
+ ct:fail({wrong_version, [{got, Version},
+ {expected, Ver}]});
_ ->
- case Version of
- "HTTP/1.1" ->
- ok;
+ case Version of
+ "HTTP/1.1" ->
+ ok;
_ ->
- tsf({wrong_version, [{got, Version},
- {expected, "HTTP/1.1"}]})
- end
+ ct:fail({wrong_version, [{got, Version},
+ {expected, "HTTP/1.1"}]})
+ end
end.
check_status_code(StatusCode, [], Options) ->
- tsf({wrong_status_code, [{got, StatusCode}, {expected, Options}]});
+ ct:fail({wrong_status_code, [{got, StatusCode}, {expected, Options}]});
check_status_code(StatusCode, Current = [_ | Rest], Options) ->
case lists:keysearch(statuscode, 1, Current) of
{value, {statuscode, StatusCode}} ->
@@ -332,7 +276,7 @@ check_status_code(StatusCode, Current = [_ | Rest], Options) ->
{value, {statuscode, _OtherStatus}} ->
check_status_code(StatusCode, Rest, Options);
false ->
- tsf({wrong_status_code, [{got, StatusCode}, {expected, Options}]})
+ ct:fail({wrong_status_code, [{got, StatusCode}, {expected, Options}]})
end.
do_validate(_, [], _, _) ->
@@ -345,9 +289,9 @@ do_validate(Header, [{header, HeaderField}|Rest], N, P) ->
{value, {LowerHeaderField, _Value}} ->
ok;
false ->
- tsf({missing_header_field, LowerHeaderField, Header});
+ ct:fail({missing_header_field, LowerHeaderField, Header});
_ ->
- tsf({missing_header_field, LowerHeaderField, Header})
+ ct:fail({missing_header_field, LowerHeaderField, Header})
end,
do_validate(Header, Rest, N, P);
do_validate(Header, [{header, HeaderField, Value}|Rest],N,P) ->
@@ -356,15 +300,15 @@ do_validate(Header, [{header, HeaderField, Value}|Rest],N,P) ->
{value, {LowerHeaderField, Value}} ->
ok;
false ->
- tsf({wrong_header_field_value, LowerHeaderField, Header});
+ ct:fail({wrong_header_field_value, LowerHeaderField, Header, Value});
_ ->
- tsf({wrong_header_field_value, LowerHeaderField, Header})
+ ct:fail({wrong_header_field_value, LowerHeaderField, Header, Value})
end,
do_validate(Header, Rest, N, P);
-do_validate(Header,[{no_last_modified, HeaderField}|Rest],N,P) ->
+do_validate(Header,[{no_header, HeaderField}|Rest],N,P) ->
case lists:keysearch(HeaderField,1,Header) of
{value,_} ->
- tsf({wrong_header_field_value, HeaderField, Header});
+ ct:fail({wrong_header_field_value, HeaderField, Header});
_ ->
ok
end,
@@ -373,23 +317,23 @@ do_validate(Header, [_Unknown | Rest], N, P) ->
do_validate(Header, Rest, N, P).
is_expect(RequestStr) ->
- case inets_regexp:match(RequestStr, "xpect:100-continue") of
- {match, _, _}->
+ case re:run(RequestStr, "xpect:100-continue", [{capture, none}]) of
+ match->
true;
- _ ->
+ nomatch ->
false
end.
%% OTP-5775, content-length
check_body("GET /cgi-bin/erl/httpd_example:get_bin HTTP/1.0\r\n\r\n", 200, "text/html", Length, _Body) when (Length =/= 274) ->
- tsf(content_length_error);
+ ct:fail(content_length_error);
check_body("GET /cgi-bin/cgi_echo HTTP/1.0\r\n\r\n", 200, "text/plain",
_, Body) ->
case size(Body) of
100 ->
ok;
_ ->
- tsf(content_length_error)
+ ct:fail(content_length_error)
end;
check_body(RequestStr, 200, "text/html", _, Body) ->
@@ -404,16 +348,3 @@ check_body(RequestStr, 200, "text/html", _, Body) ->
check_body(_, _, _, _,_) ->
ok.
-print(Proto, Data, #state{print = true}) ->
- test_server:format("Received ~p: ~p~n", [Proto, Data]);
-print(_, _, #state{print = false}) ->
- ok.
-
-
-tsp(F) ->
- inets_test_lib:tsp(F).
-tsp(F, A) ->
- inets_test_lib:tsp(F, A).
-
-tsf(Reason) ->
- inets_test_lib:tsf(Reason).
diff --git a/lib/inets/test/httpd_time_test.erl b/lib/inets/test/httpd_time_test.erl
index 0bb457f9b9..e858ddf4f6 100644
--- a/lib/inets/test/httpd_time_test.erl
+++ b/lib/inets/test/httpd_time_test.erl
@@ -1,18 +1,19 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2001-2011. All Rights Reserved.
+%% Copyright Ericsson AB 2001-2016. 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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% 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.
+%% http://www.apache.org/licenses/LICENSE-2.0
+%%
+%% Unless required by applicable law or agreed to in writing, software
+%% distributed under the License is distributed on an "AS IS" BASIS,
+%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+%% See the License for the specific language governing permissions and
+%% limitations under the License.
%%
%% %CopyrightEnd%
%%
@@ -116,13 +117,14 @@ main(N, SocketType, Host, Port, Time)
loop(Pollers, Timeout) ->
d("loop -> entry when"
"~n Timeout: ~p", [Timeout]),
- Start = t(),
+ Start = erlang:monotonic_time(),
+
receive
{'EXIT', Pid, {poller_stat_failure, SocketType, Host, Port, Time, Reason}} ->
case is_poller(Pid, Pollers) of
true ->
error_msg("received unexpected exit from poller ~p~n"
- "befor completion of test "
+ "before completion of test "
"after ~p micro sec"
"~n SocketType: ~p"
"~n Host: ~p"
@@ -133,7 +135,7 @@ loop(Pollers, Timeout) ->
false ->
error_msg("received unexpected ~p from ~p"
"befor completion of test", [Reason, Pid]),
- loop(Pollers, to(Timeout, Start))
+ loop(Pollers, Timeout - inets_lib:millisec_passed(Start))
end;
{poller_stat_failure, Pid, {SocketType, Host, Port, Time, Reason}} ->
@@ -384,63 +386,34 @@ validate(ExpStatusCode, _SocketType, _Socket, Response) ->
%% Sz = sz(Response),
%% trash_the_rest(Socket, Sz),
%% inets_test_lib:close(SocketType, Socket),
- case inets_regexp:split(Response," ") of
- {ok, ["HTTP/1.0", ExpStatusCode|_]} ->
+ case re:split(Response," ", [{return, list}]) of
+ ["HTTP/1.0", ExpStatusCode|_] ->
ok;
- {ok, ["HTTP/1.0", StatusCode|_]} ->
+ ["HTTP/1.0", StatusCode|_] ->
error_msg("Unexpected status code: ~p (~s). "
"Expected status code: ~p (~s)",
[StatusCode, status_to_message(StatusCode),
ExpStatusCode, status_to_message(ExpStatusCode)]),
exit({unexpected_response_code, StatusCode, ExpStatusCode});
- {ok, ["HTTP/1.1", ExpStatusCode|_]} ->
+ ["HTTP/1.1", ExpStatusCode|_] ->
ok;
- {ok, ["HTTP/1.1", StatusCode|_]} ->
+ ["HTTP/1.1", StatusCode|_] ->
error_msg("Unexpected status code: ~p (~s). "
"Expected status code: ~p (~s)",
[StatusCode, status_to_message(StatusCode),
ExpStatusCode, status_to_message(ExpStatusCode)]),
exit({unexpected_response_code, StatusCode, ExpStatusCode});
- {ok, Unexpected} ->
- error_msg("Unexpected response split: ~p (~s)",
- [Unexpected, Response]),
- exit({unexpected_response, Unexpected, Response});
- {error, Reason} ->
+ {error, Reason} ->
error_msg("Failed processing response: ~p (~s)",
[Reason, Response]),
- exit({failed_response_processing, Reason, Response})
- end.
-
-
-trash_the_rest(Socket, N) ->
- receive
- {ssl, Socket, Trash} ->
- trash_the_rest(Socket, add(N,sz(Trash)));
- {ssl_closed, Socket} ->
- N;
- {ssl_error, Socket, Error} ->
- exit({connection_error, Error});
-
- {tcp, Socket, Trash} ->
- trash_the_rest(Socket, add(N,sz(Trash)));
- {tcp_closed, Socket} ->
- N;
- {tcp_error, Socket, Error} ->
- exit({connection_error, Error})
-
- after 10000 ->
- exit({connection_timed_out, N})
+ exit({failed_response_processing, Reason, Response});
+ Unexpected ->
+ error_msg("Unexpected response split: ~p (~s)",
+ [Unexpected, Response]),
+ exit({unexpected_response, Unexpected, Response})
end.
-add(N1,N2) when is_integer(N1) andalso is_integer(N2) ->
- N1 + N2;
-add(N1,_) when is_integer(N1) ->
- N1;
-add(_,N2) when is_integer(N2) ->
- N2.
-
-
sz(L) when is_list(L) ->
length(lists:flatten(L));
sz(B) when is_binary(B) ->
@@ -505,17 +478,6 @@ status_to_message(Code) -> io_lib:format("Unknown status code: ~p",[Code]).
%% ----------------------------------------------------------------
-to(To, Start) ->
- To - (t() - Start).
-
-%% Time in milli seconds
-t() ->
- {A,B,C} = erlang:now(),
- A*1000000000+B*1000+(C div 1000).
-
-
-%% ----------------------------------------------------------------
-
% close(Socket) ->
diff --git a/lib/inets/test/inets_SUITE.erl b/lib/inets/test/inets_SUITE.erl
index 6510c70d08..5eaf3a28a0 100644
--- a/lib/inets/test/inets_SUITE.erl
+++ b/lib/inets/test/inets_SUITE.erl
@@ -1,18 +1,19 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1997-2013. All Rights Reserved.
+%% Copyright Ericsson AB 1997-2015. 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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% 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.
+%% http://www.apache.org/licenses/LICENSE-2.0
+%%
+%% Unless required by applicable law or agreed to in writing, software
+%% distributed under the License is distributed on an "AS IS" BASIS,
+%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+%% See the License for the specific language governing permissions and
+%% limitations under the License.
%%
%% %CopyrightEnd%
%%
@@ -20,7 +21,6 @@
-module(inets_SUITE).
-include_lib("common_test/include/ct.hrl").
--include("test_server_line.hrl").
-include("inets_test_lib.hrl").
%% Note: This directive should only be used in test suites.
@@ -28,18 +28,24 @@
-define(NUM_DEFAULT_SERVICES, 1).
-suite() -> [{ct_hooks,[ts_install_cth]}].
+suite() ->
+ [{ct_hooks,[ts_install_cth]},
+ {timetrap,{seconds,5}}
+ ].
all() ->
- [{group, app_test}, {group, appup_test},
+ [{group, app_test},
{group, services_test}, httpd_reload].
groups() ->
[{services_test, [],
- [start_inets, start_httpc, start_httpd, start_ftpc,
- start_tftpd]},
- {app_test, [], [{inets_app_test, all}]},
- {appup_test, [], [{inets_appup_test, all}]}].
+ [start_inets,
+ start_httpc,
+ start_httpd,
+ start_ftpc,
+ start_tftpd
+ ]},
+ {app_test, [], [app, appup]}].
init_per_group(_GroupName, Config) ->
Config.
@@ -47,9 +53,6 @@ init_per_group(_GroupName, Config) ->
end_per_group(_GroupName, Config) ->
Config.
-
-
-
%%--------------------------------------------------------------------
%% Function: init_per_suite(Config) -> Config
%% Config - [tuple()]
@@ -83,6 +86,10 @@ end_per_suite(_Config) ->
%% 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(httpd_reload, Config) ->
+ inets:stop(),
+ ct:timetrap({seconds, 40}),
+ Config;
init_per_testcase(_Case, Config) ->
inets:stop(),
Config.
@@ -101,15 +108,18 @@ end_per_testcase(_, Config) ->
%%-------------------------------------------------------------------------
%% Test cases starts here.
%%-------------------------------------------------------------------------
+app() ->
+ [{doc, "Test that the inets app file is ok"}].
+app(Config) when is_list(Config) ->
+ ok = ?t:app_test(inets).
+%%--------------------------------------------------------------------
+appup() ->
+ [{doc, "Test that the inets appup file is ok"}].
+appup(Config) when is_list(Config) ->
+ ok = ?t:appup_test(inets).
-
-
-%%-------------------------------------------------------------------------
-
-start_inets(doc) ->
- ["Test inets API functions"];
-start_inets(suite) ->
- [];
+start_inets() ->
+ [{doc, "Test inets API functions"}].
start_inets(Config) when is_list(Config) ->
[_|_] = inets:service_names(),
@@ -133,142 +143,92 @@ start_inets(Config) when is_list(Config) ->
ok = inets:start(permanent),
ok = inets:stop().
-
%%-------------------------------------------------------------------------
-start_httpc(doc) ->
- ["Start/stop of httpc service"];
-start_httpc(suite) ->
- [];
+start_httpc() ->
+ [{doc, "Start/stop of httpc service"}].
start_httpc(Config) when is_list(Config) ->
process_flag(trap_exit, true),
- tsp("start_httpc -> entry with"
- "~n Config: ~p", [Config]),
+ PrivDir = proplists:get_value(priv_dir, Config),
- PrivDir = ?config(priv_dir, Config),
-
- tsp("start_httpc -> start (empty) inets"),
ok = inets:start(),
-
- tsp("start_httpc -> start httpc (as inets service) with profile foo"),
{ok, Pid0} = inets:start(httpc, [{profile, foo}]),
- tsp("start_httpc -> check running services"),
Pids0 = [ServicePid || {_, ServicePid} <- inets:services()],
true = lists:member(Pid0, Pids0),
[_|_] = inets:services_info(),
- tsp("start_httpc -> stop httpc"),
inets:stop(httpc, Pid0),
- tsp("start_httpc -> sleep some"),
- test_server:sleep(100),
+ ct:sleep(100),
- tsp("start_httpc -> check running services"),
Pids1 = [ServicePid || {_, ServicePid} <- inets:services()],
false = lists:member(Pid0, Pids1),
- tsp("start_httpc -> start httpc (stand-alone) with profile bar"),
{ok, Pid1} = inets:start(httpc, [{profile, bar}], stand_alone),
- tsp("start_httpc -> check running services"),
Pids2 = [ServicePid || {_, ServicePid} <- inets:services()],
false = lists:member(Pid1, Pids2),
- tsp("start_httpc -> stop httpc"),
ok = inets:stop(stand_alone, Pid1),
receive
{'EXIT', Pid1, shutdown} ->
ok
after 100 ->
- tsf(stand_alone_not_shutdown)
+ ct:fail(stand_alone_not_shutdown)
end,
- tsp("start_httpc -> stop inets"),
ok = inets:stop(),
- tsp("start_httpc -> unload inets"),
application:load(inets),
-
- tsp("start_httpc -> set inets environment (httpc profile foo)"),
application:set_env(inets, services, [{httpc,[{profile, foo},
{data_dir, PrivDir}]}]),
-
- tsp("start_httpc -> start inets"),
ok = inets:start(),
- tsp("start_httpc -> check running services"),
(?NUM_DEFAULT_SERVICES + 1) = length(inets:services()),
- tsp("start_httpc -> unset inets env"),
application:unset_env(inets, services),
-
- tsp("start_httpc -> stop inets"),
ok = inets:stop(),
-
- tsp("start_httpc -> start (empty) inets"),
ok = inets:start(),
- tsp("start_httpc -> start inets httpc service with profile foo"),
{ok, Pid3} = inets:start(httpc, [{profile, foo}]),
-
- tsp("start_httpc -> stop inets service httpc with profile foo"),
ok = inets:stop(httpc, foo),
-
- tsp("start_httpc -> check running services"),
Pids3 = [ServicePid || {_, ServicePid} <- inets:services()],
false = lists:member(Pid3, Pids3),
-
- tsp("start_httpc -> stop inets"),
- ok = inets:stop(),
-
- tsp("start_httpc -> done"),
- ok.
-
+ ok = inets:stop().
%%-------------------------------------------------------------------------
-start_httpd(doc) ->
- ["Start/stop of httpd service"];
-start_httpd(suite) ->
- [];
+start_httpd() ->
+ [{doc, "Start/stop of httpd service"}].
start_httpd(Config) when is_list(Config) ->
process_flag(trap_exit, true),
- i("start_httpd -> entry with"
- "~n Config: ~p", [Config]),
- PrivDir = ?config(priv_dir, Config),
+ PrivDir = proplists:get_value(priv_dir, Config),
HttpdConf = [{server_name, "httpd_test"}, {server_root, PrivDir},
- {document_root, PrivDir}, {bind_address, "localhost"}],
+ {document_root, PrivDir}, {bind_address, any}],
- i("start_httpd -> start inets"),
ok = inets:start(),
-
- i("start_httpd -> start httpd service"),
{ok, Pid0} = inets:start(httpd, [{port, 0}, {ipfamily, inet} | HttpdConf]),
Pids0 = [ServicePid || {_, ServicePid} <- inets:services()],
true = lists:member(Pid0, Pids0),
[_|_] = inets:services_info(),
- i("start_httpd -> stop httpd service"),
inets:stop(httpd, Pid0),
- test_server:sleep(500),
+ ct:sleep(500),
Pids1 = [ServicePid || {_, ServicePid} <- inets:services()],
false = lists:member(Pid0, Pids1),
- i("start_httpd -> start (stand-alone) httpd service"),
{ok, Pid1} =
inets:start(httpd, [{port, 0}, {ipfamily, inet} | HttpdConf],
stand_alone),
Pids2 = [ServicePid || {_, ServicePid} <- inets:services()],
false = lists:member(Pid1, Pids2),
- i("start_httpd -> stop (stand-alone) httpd service"),
ok = inets:stop(stand_alone, Pid1),
receive
{'EXIT', Pid1, shutdown} ->
ok
after 100 ->
- test_server:fail(stand_alone_not_shutdown)
+ ct:fail(stand_alone_not_shutdown)
end,
- i("start_httpd -> stop inets"),
ok = inets:stop(),
File0 = filename:join(PrivDir, "httpd.conf"),
{ok, Fd0} = file:open(File0, [write]),
@@ -276,17 +236,12 @@ start_httpd(Config) when is_list(Config) ->
ok = file:write(Fd0, Str),
file:close(Fd0),
- i("start_httpd -> [application] load inets"),
application:load(inets),
- i("start_httpd -> [application] set httpd services env with proplist-file"),
application:set_env(inets,
services, [{httpd, [{proplist_file, File0}]}]),
- i("start_httpd -> start inets"),
ok = inets:start(),
(?NUM_DEFAULT_SERVICES + 1) = length(inets:services()),
- i("start_httpd -> [application] unset services env"),
application:unset_env(inets, services),
- i("start_httpd -> stop inets"),
ok = inets:stop(),
File1 = filename:join(PrivDir, "httpd_apache.conf"),
@@ -299,116 +254,84 @@ start_httpd(Config) when is_list(Config) ->
file:write(Fd1, "Port 0\r\n"),
file:close(Fd1),
- i("start_httpd -> [application] load inets"),
application:load(inets),
- i("start_httpd -> [application] set httpd services env with file"),
application:set_env(inets,
services, [{httpd, [{file, File1}]}]),
- i("start_httpd -> start inets"),
ok = inets:start(),
(?NUM_DEFAULT_SERVICES + 1) = length(inets:services()),
- i("start_httpd -> [application] unset services env"),
application:unset_env(inets, services),
- i("start_httpd -> stop inets"),
ok = inets:stop(),
%% OLD format
- i("start_httpd -> [application] load inets"),
application:load(inets),
- i("start_httpd -> [application] set httpd services OLD env"),
application:set_env(inets,
services, [{httpd, File1}]),
- i("start_httpd -> start inets"),
ok = inets:start(),
(?NUM_DEFAULT_SERVICES + 1) = length(inets:services()),
- i("start_httpd -> [application] unset services enc"),
application:unset_env(inets, services),
- i("start_httpd -> stop inets"),
ok = inets:stop(),
-
- i("start_httpd -> start inets"),
ok = inets:start(),
- i("start_httpd -> try (and fail) start httpd service - server_name"),
{error, {missing_property, server_name}} =
inets:start(httpd, [{port, 0},
{server_root, PrivDir},
{document_root, PrivDir},
{bind_address, "localhost"}]),
- i("start_httpd -> try (and fail) start httpd service - missing document_root"),
{error, {missing_property, document_root}} =
inets:start(httpd, [{port, 0},
{server_name, "httpd_test"},
{server_root, PrivDir},
{bind_address, "localhost"}]),
- i("start_httpd -> try (and fail) start httpd service - missing server_root"),
{error, {missing_property, server_root}} =
inets:start(httpd, [{port, 0},
{server_name, "httpd_test"},
{document_root, PrivDir},
{bind_address, "localhost"}]),
- i("start_httpd -> try (and fail) start httpd service - missing port"),
{error, {missing_property, port}} =
inets:start(httpd, HttpdConf),
- i("start_httpd -> stop inets"),
- ok = inets:stop(),
- i("start_httpd -> done"),
- ok.
-
+ ok = inets:stop().
%%-------------------------------------------------------------------------
start_ftpc(doc) ->
- ["Start/stop of ftpc service"];
-start_ftpc(suite) ->
- [];
-start_ftpc(Config) when is_list(Config) ->
+ [{doc, "Start/stop of ftpc service"}];
+start_ftpc(Config0) when is_list(Config0) ->
process_flag(trap_exit, true),
ok = inets:start(),
- try
- begin
- {_Tag, FtpdHost} = ftp_suite_lib:dirty_select_ftpd_host(Config),
- case inets:start(ftpc, [{host, FtpdHost}]) of
- {ok, Pid0} ->
- Pids0 = [ServicePid || {_, ServicePid} <-
- inets:services()],
- true = lists:member(Pid0, Pids0),
- [_|_] = inets:services_info(),
- inets:stop(ftpc, Pid0),
- test_server:sleep(100),
- Pids1 = [ServicePid || {_, ServicePid} <-
- inets:services()],
- false = lists:member(Pid0, Pids1),
- {ok, Pid1} =
- inets:start(ftpc, [{host, FtpdHost}], stand_alone),
- Pids2 = [ServicePid || {_, ServicePid} <-
- inets:services()],
- false = lists:member(Pid1, Pids2),
- ok = inets:stop(stand_alone, Pid1),
- receive
- {'EXIT', Pid1, shutdown} ->
- ok
- after 100 ->
- tsf(stand_alone_not_shutdown)
- end,
- ok = inets:stop(),
- ok;
- _ ->
- {skip, "Unable to reach selected FTP server " ++ FtpdHost}
- end
- end
- catch
- throw:{error, not_found} ->
- {skip, "No available FTP servers"}
+ case ftp_SUITE:init_per_suite(Config0) of
+ {skip, _} = Skip ->
+ Skip;
+ Config ->
+ FtpdHost = proplists:get_value(ftpd_host,Config),
+ {ok, Pid0} = inets:start(ftpc, [{host, FtpdHost}]),
+ Pids0 = [ServicePid || {_, ServicePid} <-
+ inets:services()],
+ true = lists:member(Pid0, Pids0),
+ [_|_] = inets:services_info(),
+ inets:stop(ftpc, Pid0),
+ ct:sleep(100),
+ Pids1 = [ServicePid || {_, ServicePid} <-
+ inets:services()],
+ false = lists:member(Pid0, Pids1),
+ {ok, Pid1} =
+ inets:start(ftpc, [{host, FtpdHost}], stand_alone),
+ Pids2 = [ServicePid || {_, ServicePid} <-
+ inets:services()],
+ false = lists:member(Pid1, Pids2),
+ ok = inets:stop(stand_alone, Pid1),
+ receive
+ {'EXIT', Pid1, shutdown} ->
+ ok
+ after 100 ->
+ ct:fail(stand_alone_not_shutdown)
+ end,
+ ok = inets:stop(),
+ catch ftp_SUITE:end_per_SUITE(Config)
end.
-
-
%%-------------------------------------------------------------------------
-start_tftpd(doc) ->
- ["Start/stop of tfpd service"];
-start_tftpd(suite) ->
- [];
+start_tftpd() ->
+ [{doc, "Start/stop of tfpd service"}].
start_tftpd(Config) when is_list(Config) ->
process_flag(trap_exit, true),
ok = inets:start(),
@@ -417,7 +340,7 @@ start_tftpd(Config) when is_list(Config) ->
true = lists:member(Pid0, Pids0),
[_|_] = inets:services_info(),
inets:stop(tftpd, Pid0),
- test_server:sleep(100),
+ ct:sleep(100),
Pids1 = [ServicePid || {_, ServicePid} <- inets:services()],
false = lists:member(Pid0, Pids1),
{ok, Pid1} =
@@ -429,7 +352,7 @@ start_tftpd(Config) when is_list(Config) ->
{'EXIT', Pid1, shutdown} ->
ok
after 100 ->
- test_server:fail(stand_alone_not_shutdown)
+ ct:fail(stand_alone_not_shutdown)
end,
ok = inets:stop(),
application:load(inets),
@@ -440,52 +363,40 @@ start_tftpd(Config) when is_list(Config) ->
application:unset_env(inets, services),
ok = inets:stop().
-
%%-------------------------------------------------------------------------
-httpd_reload(doc) ->
- ["Reload httpd configuration without restarting service"];
-httpd_reload(suite) ->
- [];
+httpd_reload() ->
+ [{doc, "Reload httpd configuration without restarting service"}].
httpd_reload(Config) when is_list(Config) ->
process_flag(trap_exit, true),
- i("httpd_reload -> starting"),
- PrivDir = ?config(priv_dir, Config),
- DataDir = ?config(data_dir, Config),
+ PrivDir = proplists:get_value(priv_dir, Config),
+ DataDir = proplists:get_value(data_dir, Config),
HttpdConf = [{server_name, "httpd_test"},
{server_root, PrivDir},
{document_root, PrivDir},
{bind_address, "localhost"}],
- i("httpd_reload -> start inets"),
-
ok = inets:start(),
- test_server:sleep(5000),
- i("httpd_reload -> inets started - start httpd service"),
+ ct:sleep(5000),
- {ok, Pid0} = inets:start(httpd, [{port, 0}, {ipfamily, inet} | HttpdConf]),
- test_server:sleep(5000),
- i("httpd_reload -> httpd service started (~p) - get port", [Pid0]),
+ {ok, Pid0} = inets:start(httpd, [{port, 0},
+ {ipfamily, inet} | HttpdConf]),
+ ct:sleep(5000),
[{port, Port0}] = httpd:info(Pid0, [port]),
- test_server:sleep(5000),
- i("httpd_reload -> Port: ~p - get document root", [Port0]),
+ ct:sleep(5000),
[{document_root, PrivDir}] = httpd:info(Pid0, [document_root]),
- test_server:sleep(5000),
- i("httpd_reload -> document root: ~p - reload config", [PrivDir]),
+ ct:sleep(5000),
ok = httpd:reload_config([{port, Port0}, {ipfamily, inet},
{server_name, "httpd_test"},
{server_root, PrivDir},
{document_root, DataDir},
{bind_address, "localhost"}], non_disturbing),
- test_server:sleep(5000),
- io:format("~w:~w:httpd_reload - reloaded - get document root~n", [?MODULE, ?LINE]),
-
+ ct:sleep(5000),
[{document_root, DataDir}] = httpd:info(Pid0, [document_root]),
- test_server:sleep(5000),
- i("httpd_reload -> document root: ~p - reload config", [DataDir]),
+ ct:sleep(5000),
ok = httpd:reload_config([{port, Port0}, {ipfamily, inet},
{server_name, "httpd_test"},
@@ -538,36 +449,5 @@ httpd_reload(Config) when is_list(Config) ->
ok = inets:stop(httpd, Pid1),
application:unset_env(inets, services),
- ok = inets:stop(),
- i("httpd_reload -> starting"),
- ok.
-
-
-tsf(Reason) ->
- test_server:fail(Reason).
-
-tsp(F) ->
- tsp(F, []).
-tsp(F, A) ->
- Timestamp = formated_timestamp(),
- test_server:format("** ~s ** ~p ~p:" ++ F ++ "~n", [Timestamp, self(), ?MODULE | A]).
-
-i(F) ->
- i(F, []).
-
-i(F, A) ->
- Timestamp = formated_timestamp(),
- io:format("*** ~s ~w:" ++ F ++ "~n", [Timestamp, ?MODULE | A]).
-
-formated_timestamp() ->
- format_timestamp( os:timestamp() ).
-
-format_timestamp({_N1, _N2, N3} = Now) ->
- {Date, Time} = calendar:now_to_datetime(Now),
- {YYYY,MM,DD} = Date,
- {Hour,Min,Sec} = Time,
- FormatDate =
- io_lib:format("~.4w:~.2.0w:~.2.0w ~.2.0w:~.2.0w:~.2.0w 4~w",
- [YYYY,MM,DD,Hour,Min,Sec,round(N3/1000)]),
- lists:flatten(FormatDate).
+ ok = inets:stop().
diff --git a/lib/inets/test/inets_app_test.erl b/lib/inets/test/inets_app_test.erl
deleted file mode 100644
index eabfa69f7c..0000000000
--- a/lib/inets/test/inets_app_test.erl
+++ /dev/null
@@ -1,307 +0,0 @@
-%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2002-2012. 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: Verify the application specifics of the inets application
-%%----------------------------------------------------------------------
--module(inets_app_test).
-
--compile(export_all).
-
--include("inets_test_lib.hrl").
-
-
-% t() -> megaco_test_lib:t(?MODULE).
-% t(Case) -> megaco_test_lib:t({?MODULE, Case}).
-
-
-%% Test server callbacks
-init_per_testcase(undef_funcs, Config) ->
- NewConfig = lists:keydelete(watchdog, 1, Config),
- Dog = test_server:timetrap(inets_test_lib:minutes(10)),
-
- %% We need to check if there is a point to run this test.
- %% On some platforms, crypto will not build, which in turn
- %% causes ssl to not build (at this time, this will
- %% change in the future).
- %% So, we first check if we can start crypto, and if not,
- %% we skip this test case!
- ?ENSURE_STARTED(crypto),
-
- [{watchdog, Dog}| NewConfig];
-init_per_testcase(_, Config) ->
- Config.
-
-end_per_testcase(_Case, Config) ->
- Config.
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-
-all() ->
- [fields, modules, exportall, app_depend, undef_funcs].
-
-groups() ->
- [].
-
-init_per_group(_GroupName, Config) ->
- Config.
-
-end_per_group(_GroupName, Config) ->
- Config.
-
-
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-
-init_per_suite(suite) -> [];
-init_per_suite(doc) -> [];
-init_per_suite(Config) when is_list(Config) ->
- case is_app(inets) of
- {ok, AppFile} ->
- io:format("AppFile: ~n~p~n", [AppFile]),
- inets:print_version_info(),
- [{app_file, AppFile}|Config];
- {error, Reason} ->
- fail(Reason)
- end.
-
-is_app(App) ->
- LibDir = code:lib_dir(App),
- File = filename:join([LibDir, "ebin", atom_to_list(App) ++ ".app"]),
- case file:consult(File) of
- {ok, [{application, App, AppFile}]} ->
- {ok, AppFile};
- Error ->
- {error, {invalid_format, Error}}
- end.
-
-
-end_per_suite(suite) -> [];
-end_per_suite(doc) -> [];
-end_per_suite(Config) when is_list(Config) ->
- Config.
-
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-
-fields(suite) ->
- [];
-fields(doc) ->
- [];
-fields(Config) when is_list(Config) ->
- AppFile = key1search(app_file, Config),
- Fields = [vsn, description, modules, registered, applications],
- case check_fields(Fields, AppFile, []) of
- [] ->
- ok;
- Missing ->
- fail({missing_fields, Missing})
- end.
-
-check_fields([], _AppFile, Missing) ->
- Missing;
-check_fields([Field|Fields], AppFile, Missing) ->
- check_fields(Fields, AppFile, check_field(Field, AppFile, Missing)).
-
-check_field(Name, AppFile, Missing) ->
- io:format("checking field: ~p~n", [Name]),
- case lists:keymember(Name, 1, AppFile) of
- true ->
- Missing;
- false ->
- [Name|Missing]
- end.
-
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-
-modules(suite) ->
- [];
-modules(doc) ->
- [];
-modules(Config) when is_list(Config) ->
- AppFile = key1search(app_file, Config),
- Mods = key1search(modules, AppFile),
- EbinList = get_ebin_mods(inets),
- case missing_modules(Mods, EbinList, []) of
- [] ->
- ok;
- Missing ->
- throw({error, {missing_modules, Missing}})
- end,
- case extra_modules(Mods, EbinList, []) of
- [] ->
- ok;
- Extra ->
- throw({error, {extra_modules, Extra}})
- end,
- {ok, Mods}.
-
-get_ebin_mods(App) ->
- LibDir = code:lib_dir(App),
- EbinDir = filename:join([LibDir,"ebin"]),
- {ok, Files0} = file:list_dir(EbinDir),
- Files1 = [lists:reverse(File) || File <- Files0],
- [list_to_atom(lists:reverse(Name)) || [$m,$a,$e,$b,$.|Name] <- Files1].
-
-
-missing_modules([], _Ebins, Missing) ->
- Missing;
-missing_modules([Mod|Mods], Ebins, Missing) ->
- case lists:member(Mod, Ebins) of
- true ->
- missing_modules(Mods, Ebins, Missing);
- false ->
- io:format("missing module: ~p~n", [Mod]),
- missing_modules(Mods, Ebins, [Mod|Missing])
- end.
-
-
-extra_modules(_Mods, [], Extra) ->
- Extra;
-extra_modules(Mods, [Mod|Ebins], Extra) ->
- case lists:member(Mod, Mods) of
- true ->
- extra_modules(Mods, Ebins, Extra);
- false ->
- io:format("supefluous module: ~p~n", [Mod]),
- extra_modules(Mods, Ebins, [Mod|Extra])
- end.
-
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-
-
-exportall(suite) ->
- [];
-exportall(doc) ->
- [];
-exportall(Config) when is_list(Config) ->
- AppFile = key1search(app_file, Config),
- Mods = key1search(modules, AppFile),
- check_export_all(Mods).
-
-
-check_export_all([]) ->
- ok;
-check_export_all([Mod|Mods]) ->
- case (catch apply(Mod, module_info, [compile])) of
- {'EXIT', {undef, _}} ->
- check_export_all(Mods);
- O ->
- case lists:keysearch(options, 1, O) of
- false ->
- check_export_all(Mods);
- {value, {options, List}} ->
- case lists:member(export_all, List) of
- true ->
- throw({error, {export_all, Mod}});
- false ->
- check_export_all(Mods)
- end
- end
- end.
-
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-
-app_depend(suite) ->
- [];
-app_depend(doc) ->
- [];
-app_depend(Config) when is_list(Config) ->
- AppFile = key1search(app_file, Config),
- Apps = key1search(applications, AppFile),
- check_apps(Apps).
-
-
-check_apps([]) ->
- ok;
-check_apps([App|Apps]) ->
- case is_app(App) of
- {ok, _} ->
- check_apps(Apps);
- Error ->
- throw({error, {missing_app, {App, Error}}})
- end.
-
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-
-undef_funcs(suite) ->
- [];
-undef_funcs(doc) ->
- [];
-undef_funcs(Config) when is_list(Config) ->
- App = inets,
- AppFile = key1search(app_file, Config),
- Mods = key1search(modules, AppFile),
- Root = code:root_dir(),
- LibDir = code:lib_dir(App),
- EbinDir = filename:join([LibDir,"ebin"]),
- XRefTestName = undef_funcs_make_name(App, xref_test_name),
- {ok, XRef} = xref:start(XRefTestName),
- ok = xref:set_default(XRef,
- [{verbose,false},{warnings,false}]),
- XRefName = undef_funcs_make_name(App, xref_name),
- {ok, XRefName} = xref:add_release(XRef, Root, {name, XRefName}),
- {ok, App} = xref:replace_application(XRef, App, EbinDir),
- {ok, Undefs} = xref:analyze(XRef, undefined_function_calls),
- xref:stop(XRef),
- analyze_undefined_function_calls(Undefs, Mods, []).
-
-analyze_undefined_function_calls([], _, []) ->
- ok;
-analyze_undefined_function_calls([], _, AppUndefs) ->
- exit({suite_failed, {undefined_function_calls, AppUndefs}});
-analyze_undefined_function_calls([{{Mod, _F, _A}, _C} = AppUndef|Undefs],
- AppModules, AppUndefs) ->
- %% Check that this module is our's
- case lists:member(Mod,AppModules) of
- true ->
- {Calling,Called} = AppUndef,
- {Mod1,Func1,Ar1} = Calling,
- {Mod2,Func2,Ar2} = Called,
- io:format("undefined function call: "
- "~n ~w:~w/~w calls ~w:~w/~w~n",
- [Mod1,Func1,Ar1,Mod2,Func2,Ar2]),
- analyze_undefined_function_calls(Undefs, AppModules,
- [AppUndef|AppUndefs]);
- false ->
- io:format("dropping ~p~n", [Mod]),
- analyze_undefined_function_calls(Undefs, AppModules, AppUndefs)
- end.
-
-%% This function is used simply to avoid cut-and-paste errors later...
-undef_funcs_make_name(App, PostFix) ->
- list_to_atom(atom_to_list(App) ++ "_" ++ atom_to_list(PostFix)).
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-
-
-fail(Reason) ->
- exit({suite_failed, Reason}).
-
-key1search(Key, L) ->
- case lists:keysearch(Key, 1, L) of
- undefined ->
- fail({not_found, Key, L});
- {value, {Key, Value}} ->
- Value
- end.
diff --git a/lib/inets/test/inets_appup_test.erl b/lib/inets/test/inets_appup_test.erl
deleted file mode 100644
index d563b52ae7..0000000000
--- a/lib/inets/test/inets_appup_test.erl
+++ /dev/null
@@ -1,358 +0,0 @@
-%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2002-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%
-%%
-%%
-%%----------------------------------------------------------------------
-%% Purpose: Verify the application specifics of the Inets application
-%%----------------------------------------------------------------------
--module(inets_appup_test).
-
--compile(export_all).
--compile({no_auto_import,[error/1]}).
-
--include("inets_test_lib.hrl").
-
-
- % t() -> megaco_test_lib:t(?MODULE).
- % t(Case) -> megaco_test_lib:t({?MODULE, Case}).
-
-
-%% Test server callbacks
-init_per_testcase(_Case, Config) ->
- Config.
-
-end_per_testcase(_Case, Config) ->
- Config.
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-
-all() ->
- [appup].
-
-groups() ->
- [].
-
-init_per_group(_GroupName, Config) ->
- Config.
-
-end_per_group(_GroupName, Config) ->
- Config.
-
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-
-init_per_suite(suite) -> [];
-init_per_suite(doc) -> [];
-init_per_suite(Config) when is_list(Config) ->
- AppFile = file_name(inets, ".app"),
- AppupFile = file_name(inets, ".appup"),
- [{app_file, AppFile}, {appup_file, AppupFile}|Config].
-
-
-file_name(App, Ext) ->
- LibDir = code:lib_dir(App),
- filename:join([LibDir, "ebin", atom_to_list(App) ++ Ext]).
-
-
-end_per_suite(suite) -> [];
-end_per_suite(doc) -> [];
-end_per_suite(Config) when is_list(Config) ->
- Config.
-
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-
-appup(suite) ->
- [];
-appup(doc) ->
- "perform a simple check of the appup file";
-appup(Config) when is_list(Config) ->
- AppupFile = key1search(appup_file, Config),
- AppFile = key1search(app_file, Config),
- Modules = modules(AppFile),
- check_appup(AppupFile, Modules).
-
-modules(File) ->
- case file:consult(File) of
- {ok, [{application,inets,Info}]} ->
- case lists:keysearch(modules,1,Info) of
- {value, {modules, Modules}} ->
- Modules;
- false ->
- fail({bad_appinfo, Info})
- end;
- Error ->
- fail({bad_appfile, Error})
- end.
-
-
-check_appup(AppupFile, Modules) ->
- case file:consult(AppupFile) of
- {ok, [{V, UpFrom, DownTo}]} ->
-% io:format("~p => "
-% "~n ~p"
-% "~n ~p"
-% "~n", [V, UpFrom, DownTo]),
- check_appup(V, UpFrom, DownTo, Modules);
- Else ->
- fail({bad_appupfile, Else})
- end.
-
-
-check_appup(V, UpFrom, DownTo, Modules) ->
- check_version(V),
- check_depends(up, UpFrom, Modules),
- check_depends(down, DownTo, Modules),
- ok.
-
-
-check_depends(_, [], _) ->
- ok;
-check_depends(UpDown, [Dep|Deps], Modules) ->
- check_depend(UpDown, Dep, Modules),
- check_depends(UpDown, Deps, Modules).
-
-
-check_depend(UpDown, {V, Instructions}, Modules) ->
- check_version(V),
- case check_instructions(UpDown,
- Instructions, Instructions, [], [], Modules) of
- {_Good, []} ->
- ok;
- {_, Bad} ->
- fail({bad_instructions, Bad, UpDown})
- end.
-
-
-check_instructions(_, [], _, Good, Bad, _) ->
- {lists:reverse(Good), lists:reverse(Bad)};
-check_instructions(UpDown, [Instr|Instrs], AllInstr, Good, Bad, Modules) ->
- case (catch check_instruction(UpDown, Instr, AllInstr, Modules)) of
- ok ->
- check_instructions(UpDown, Instrs, AllInstr,
- [Instr|Good], Bad, Modules);
- {error, Reason} ->
- check_instructions(UpDown, Instrs, AllInstr, Good,
- [{Instr, Reason}|Bad], Modules)
- end;
-check_instructions(UpDown, Instructions, _, _, _, _) ->
- fail({bad_instructions, {UpDown, Instructions}}).
-
-%% A new module is added
-check_instruction(up, {add_module, Module}, _, Modules)
- when is_atom(Module) ->
- check_module(Module, Modules);
-
-%% An old module is re-added
-check_instruction(down, {add_module, Module}, _, Modules)
- when is_atom(Module) ->
- case (catch check_module(Module, Modules)) of
- {error, {unknown_module, Module, Modules}} ->
- ok;
- ok ->
- error({existing_readded_module, Module})
- end;
-
-%% Removing a module on upgrade:
-%% - the module has been removed from the app-file.
-%% - check that no module depends on this (removed) module
-check_instruction(up, {remove, {Module, Pre, Post}}, _, Modules)
- when is_atom(Module), is_atom(Pre), is_atom(Post) ->
- case (catch check_module(Module, Modules)) of
- {error, {unknown_module, Module, Modules}} ->
- check_purge(Pre),
- check_purge(Post);
- ok ->
- error({existing_removed_module, Module})
- end;
-
-%% Removing a module on downgrade: the module exist
-%% in the app-file.
-check_instruction(down, {remove, {Module, Pre, Post}}, AllInstr, Modules)
- when is_atom(Module), is_atom(Pre), is_atom(Post) ->
- case (catch check_module(Module, Modules)) of
- ok ->
- check_purge(Pre),
- check_purge(Post),
- check_no_remove_depends(Module, AllInstr);
- {error, {unknown_module, Module, Modules}} ->
- error({nonexisting_removed_module, Module})
- end;
-
-check_instruction(up, {load_module, Module, Pre, Post, Depend}, _, Modules)
- when is_atom(Module), is_atom(Pre), is_atom(Post), is_list(Depend) ->
- check_module(Module, Modules),
- check_module_depend(Module, Depend, Modules),
- check_purge(Pre),
- check_purge(Post);
-
-check_instruction(down, {load_module, Module, Pre, Post, Depend}, _, Modules)
- when is_atom(Module), is_atom(Pre), is_atom(Post), is_list(Depend) ->
- check_module(Module, Modules),
- % Can not be sure that the the dependent module exists in the new appfile
- %%check_module_depend(Module, Depend, Modules),
- check_purge(Pre),
- check_purge(Post);
-
-
-
-check_instruction(up, {delete_module, Module}, _, Modules)
- when is_atom(Module) ->
- case (catch check_module(Module, Modules)) of
- {error, {unknown_module, Module, Modules}} ->
- ok;
- ok ->
- error({existing_module_deleted, Module})
- end;
-
-check_instruction(down, {delete_module, Module}, _, Modules)
- when is_atom(Module) ->
- check_module(Module, Modules);
-
-
-check_instruction(_, {apply, {Module, Function, Args}}, _, _) when is_atom(Module), is_atom(Function), is_list(Args) ->
- ok;
-
-check_instruction(_, {update, Module, supervisor}, _, Modules) when is_atom(Module) ->
- check_module(Module, Modules);
-
-check_instruction(_, {update, Module, {advanced, _}, DepMods}, _, Modules) when is_atom(Module), is_list(DepMods) ->
- check_module(Module, Modules),
- check_module_depend(Module, DepMods, Modules);
-
-check_instruction(_, {update, Module, Change, Pre, Post, Depend}, _, Modules)
- when is_atom(Module), is_atom(Pre), is_atom(Post), is_list(Depend) ->
- check_module(Module, Modules),
- check_module_depend(Module, Depend, Modules),
- check_change(Change),
- check_purge(Pre),
- check_purge(Post);
-
-check_instruction(_, {restart_application, inets}, _AllInstr, _Modules) ->
- ok;
-
-check_instruction(_, {update, Module, {advanced, _}}, _, Modules) ->
- check_module(Module, Modules);
-
-check_instruction(_, Instr, _AllInstr, _Modules) ->
- error({error, {unknown_instruction, Instr}}).
-
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-
-check_version(V) when is_list(V) ->
- ok;
-check_version(REBin) when is_binary(REBin) ->
- try
- begin
- RE = binary_to_list(REBin),
- case re:compile(RE) of
- {ok, _} ->
- ok;
- {error, _} ->
- error({bad_version, REBin})
- end
- end
- catch
- _T:_E ->
- error({bad_version, REBin})
- end;
-check_version(V) ->
- error({bad_version, V}).
-
-
-check_module(M, Modules) when is_atom(M) ->
- case lists:member(M,Modules) of
- true ->
- ok;
- false ->
- error({unknown_module, M, Modules})
- end;
-check_module(M, _) ->
- error({bad_module, M}).
-
-
-check_module_depend(M, [], _) when is_atom(M) ->
- ok;
-check_module_depend(M, Deps, Modules) when is_atom(M), is_list(Deps) ->
- case [Dep || Dep <- Deps, lists:member(Dep, Modules) == false] of
- [] ->
- ok;
- Unknown ->
- error({unknown_depend_modules, Unknown})
- end;
-check_module_depend(_M, D, _Modules) ->
- error({bad_depend, D}).
-
-
-check_no_remove_depends(_Module, []) ->
- ok;
-check_no_remove_depends(Module, [Instr|Instrs]) ->
- check_no_remove_depend(Module, Instr),
- check_no_remove_depends(Module, Instrs).
-
-check_no_remove_depend(Module, {load_module, Mod, _Pre, _Post, Depend}) ->
- case lists:member(Module, Depend) of
- true ->
- error({removed_module_in_depend, load_module, Mod, Module});
- false ->
- ok
- end;
-check_no_remove_depend(Module, {update, Mod, _Change, _Pre, _Post, Depend}) ->
- case lists:member(Module, Depend) of
- true ->
- error({removed_module_in_depend, update, Mod, Module});
- false ->
- ok
- end;
-check_no_remove_depend(_, _) ->
- ok.
-
-
-check_change(soft) ->
- ok;
-check_change({advanced, _Something}) ->
- ok;
-check_change(Change) ->
- error({bad_change, Change}).
-
-
-check_purge(soft_purge) ->
- ok;
-check_purge(brutal_purge) ->
- ok;
-check_purge(Purge) ->
- error({bad_purge, Purge}).
-
-
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-
-error(Reason) ->
- throw({error, Reason}).
-
-fail(Reason) ->
- exit({suite_failed, Reason}).
-
-key1search(Key, L) ->
- case lists:keysearch(Key, 1, L) of
- undefined ->
- fail({not_found, Key, L});
- {value, {Key, Value}} ->
- Value
- end.
diff --git a/lib/inets/test/inets_socketwrap_SUITE.erl b/lib/inets/test/inets_socketwrap_SUITE.erl
new file mode 100644
index 0000000000..18df995215
--- /dev/null
+++ b/lib/inets/test/inets_socketwrap_SUITE.erl
@@ -0,0 +1,154 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 1997-2015. All Rights Reserved.
+%%
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
+%%
+%% http://www.apache.org/licenses/LICENSE-2.0
+%%
+%% Unless required by applicable law or agreed to in writing, software
+%% distributed under the License is distributed on an "AS IS" BASIS,
+%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+%% See the License for the specific language governing permissions and
+%% limitations under the License.
+%%
+%% %CopyrightEnd%
+%%
+%%
+-module(inets_socketwrap_SUITE).
+
+-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).
+
+suite() ->
+ [{ct_hooks,[ts_install_cth]}].
+
+all() ->
+ [start_httpd_fd, start_tftpd_fd].
+
+init_per_suite(Config) ->
+ case os:type() of
+ {unix, linux} ->
+ Config;
+ _ ->
+ {skip, linux_feature}
+ end.
+
+end_per_suite(_Config) ->
+ ok.
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
+init_per_testcase(Case, Config) ->
+ end_per_testcase(Case, Config),
+ Config.
+
+end_per_testcase(_, Config) ->
+ inets:stop(),
+ Config.
+
+%%-------------------------------------------------------------------------
+start_httpd_fd() ->
+ [{doc, "Start/stop of httpd service with socket wrapper"}].
+start_httpd_fd(Config) when is_list(Config) ->
+ PrivDir = proplists:get_value(priv_dir, Config),
+ DataDir = proplists:get_value(data_dir, Config),
+ HttpdConf = [{port, 80}, {ipfamily, inet},
+ {server_name, "httpd_fd_test"}, {server_root, PrivDir},
+ {document_root, PrivDir}, {bind_address, any}],
+ case setup_node_info(node()) of
+ {skip, _} = Skip ->
+ Skip;
+ {Node, NodeArg} ->
+ InetPort = inets_test_lib:inet_port(node()),
+ ct:pal("Node: ~p Port ~p~n", [Node, InetPort]),
+ Wrapper = filename:join(DataDir, "setuid_socket_wrap"),
+ Cmd = Wrapper ++
+ " -s -httpd_80,0:" ++ integer_to_list(InetPort)
+ ++ " -p " ++ os:find_executable("erl") ++
+ " -- " ++ NodeArg,
+ ct:pal("cmd: ~p~n", [Cmd]),
+ case open_port({spawn, Cmd}, [stderr_to_stdout]) of
+ Port when is_port(Port) ->
+ wait_node_up(Node, 10),
+ ct:pal("~p", [rpc:call(Node, init, get_argument, [httpd_80])]),
+ ok = rpc:call(Node, inets, start, []),
+ {ok, Pid} = rpc:call(Node, inets, start, [httpd, HttpdConf]),
+ [{port, InetPort}] = rpc:call(Node, httpd, info, [Pid, [port]]),
+ rpc:call(Node, erlang, halt, []);
+ _ ->
+ ct:fail(open_port_failed)
+ end
+ end.
+%%-------------------------------------------------------------------------
+start_tftpd_fd() ->
+ [{doc, "Start/stop of tfpd service with socket wrapper"}].
+start_tftpd_fd(Config) when is_list(Config) ->
+ DataDir = proplists:get_value(data_dir, Config),
+ case setup_node_info(node()) of
+ {skip, _} = Skip ->
+ Skip;
+ {Node, NodeArg} ->
+ InetPort = inets_test_lib:inet_port(node()),
+ ct:pal("Node: ~p~n", [Node]),
+ Wrapper = filename:join(DataDir, "setuid_socket_wrap"),
+ Cmd = Wrapper ++
+ " -s -tftpd_69,0:" ++ integer_to_list(InetPort)
+ ++ " -p " ++ os:find_executable("erl") ++
+ " -- " ++ NodeArg,
+ ct:pal("cmd: ~p~n", [Cmd]),
+ case open_port({spawn, Cmd}, [stderr_to_stdout]) of
+ Port when is_port(Port) ->
+ wait_node_up(Node, 10),
+ ct:pal("~p", [rpc:call(Node, init, get_argument, [tftpd_69])]),
+ ok = rpc:call(Node, inets, start, []),
+ {ok, Pid} = rpc:call(Node, inets, start,
+ [tftpd,[{host, "localhost"}]]),
+ {ok, Info} = rpc:call(Node, tftp, info, [Pid]),
+ {value,{port, InetPort}} = lists:keysearch(port, 1, Info),
+ rpc:call(Node, erlang, halt, []);
+ _ ->
+ ct:fail(open_port_failed)
+ end
+ end.
+%%-------------------------------------------------------------------------
+%% Internal functions
+%%-------------------------------------------------------------------------
+setup_node_info(nonode@nohost) ->
+ {skip, needs_distributed_node};
+setup_node_info(Node) ->
+ Static = "-detached -noinput",
+ Name = "inets_fd_test",
+ NameSw = case net_kernel:longnames() of
+ false -> "-sname ";
+ _ -> "-name "
+ end,
+ StrNode =
+ Static ++ " "
+ ++ NameSw ++ " " ++ Name ++ " "
+ ++ "-setcookie " ++ atom_to_list(erlang:get_cookie()),
+ [_, Location] = string:tokens(atom_to_list(Node), "$@"),
+ TestNode = Name ++ "@" ++ Location,
+ {list_to_atom(TestNode), StrNode}.
+
+wait_node_up(Node, 0) ->
+ ct:fail({failed_to_start_node, Node});
+wait_node_up(Node, N) ->
+ ct:pal("(Node ~p: net_adm:ping(~p)~n", [node(), Node]),
+ case net_adm:ping(Node) of
+ pong ->
+ ok;
+ pang ->
+ ct:sleep(5000),
+ wait_node_up(Node, N-1)
+ end.
diff --git a/lib/inets/test/inets_socketwrap_SUITE_data/Makefile.src b/lib/inets/test/inets_socketwrap_SUITE_data/Makefile.src
new file mode 100644
index 0000000000..0933815b58
--- /dev/null
+++ b/lib/inets/test/inets_socketwrap_SUITE_data/Makefile.src
@@ -0,0 +1,39 @@
+#
+# %CopyrightBegin%
+#
+# Copyright Ericsson AB 2015-2015. All Rights Reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# %CopyrightEnd%
+#
+
+CC = @CC@
+LD = @LD@
+CFLAGS = @CFLAGS@
+CROSSLDFLAGS = @CROSSLDFLAGS@
+
+PROGS = setuid_socket_wrap@exe@
+
+.PHONY: all
+@IFEQ@ (@os@, linux-gnu)
+all: $(PROGS)
+@ELSE@
+all:
+@ENDIF@
+
+setuid_socket_wrap@exe@: setuid_socket_wrap@obj@
+ $(LD) $(CROSSLDFLAGS) -o setuid_socket_wrap setuid_socket_wrap@obj@ @LIBS@
+
+setuid_socket_wrap@obj@: setuid_socket_wrap.c
+ $(CC) -c $(CFLAGS) -o setuid_socket_wrap@obj@ setuid_socket_wrap.c
diff --git a/lib/inets/test/inets_socketwrap_SUITE_data/setuid_socket_wrap.c b/lib/inets/test/inets_socketwrap_SUITE_data/setuid_socket_wrap.c
new file mode 100644
index 0000000000..018d398956
--- /dev/null
+++ b/lib/inets/test/inets_socketwrap_SUITE_data/setuid_socket_wrap.c
@@ -0,0 +1,259 @@
+/*
+ * %CopyrightBegin%
+ *
+ * Copyright Ericsson AB 1999-2016. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * %CopyrightEnd%
+ */
+/*
+ * setuid_socket_wrap.c
+ *
+ * ./a.out [-s [tag,][addr]:[port]]* [-d [tag,][addr]:[port]]*
+ * [-r [tag,]proto]* [-p erl_path]* -- program args
+ *
+ * Where: -s = stream socket, -d datagram socket and -r means raw socket.
+ *
+ */
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <ctype.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <netdb.h>
+
+#ifndef INADDR_NONE
+#define INADDR_NONE 0xffffffff
+#endif
+
+struct sock_list {
+ struct sock_list *next;
+ int fd;
+ int type;
+ int protocol;
+ struct sockaddr_in addr;
+ char *arg;
+};
+
+int parse_addr(addr, str)
+ struct sockaddr_in *addr;
+ char *str;
+{
+ int port = 0;
+ char *cp;
+ struct hostent *hp;
+ struct servent *se;
+
+ if ((cp = strrchr(str, (int)':')) != NULL)
+ *cp++ = '\0';
+ if (cp) {
+ if (!isdigit((int)cp[0])) {
+ if ((se = getservbyname(cp, "tcp")) != NULL) {
+ port = ntohs(se->s_port);
+ } else {
+ fprintf(stderr, "unknown port %s\n", cp);
+ return -1;
+ }
+ } else {
+ port = atoi(cp);
+ }
+ }
+ if (port < 0 || port > 0xffff) {
+ fprintf(stderr, "bad port number %d\n", port);
+ return -1;
+ }
+
+ bzero(addr, sizeof(*addr));
+ addr->sin_family = AF_INET;
+ addr->sin_port = htons(port);
+ if (*str == '\000') {
+ addr->sin_addr.s_addr = INADDR_ANY;
+ } else {
+ if ((addr->sin_addr.s_addr = inet_addr(str)) == INADDR_NONE) {
+ if ((hp = gethostbyname(str)) == NULL) {
+ fprintf(stderr, "\"%s\" unknown host or address!\n", str);
+ return -1;
+ } else {
+ bcopy(hp->h_addr_list[0], &addr->sin_addr.s_addr,hp->h_length);
+ }
+ }
+ }
+ return 0;
+}
+
+struct sock_list *new_entry(type, argstr)
+ int type;
+ char *argstr;
+{
+ struct sock_list *sle;
+ char *cp;
+
+ sle = (struct sock_list *)malloc(sizeof(struct sock_list));
+ if (!sle)
+ return NULL;
+ sle->next = NULL;
+ sle->fd = -1;
+
+ if ((cp = strchr(argstr, (int)',')) != NULL) {
+ *cp++ = '\0';
+ sle->arg = argstr;
+ argstr = cp;
+ } else {
+ sle->arg = "-fd";
+ }
+ sle->type = type;
+ switch (type) {
+ case SOCK_RAW: {
+ struct protoent *pe;
+ pe = getprotobyname(argstr);
+ if (!pe) {
+ fprintf(stderr, "Unknown protocol: %s\n", argstr);
+ free(sle);
+ return NULL;
+ }
+ sle->protocol = pe->p_proto;
+ break;
+ }
+ case SOCK_STREAM:
+ case SOCK_DGRAM:
+ sle->protocol = 0;
+ if (parse_addr(&sle->addr, argstr) < 0) {
+ free(sle);
+ return NULL;
+ }
+ break;
+ }
+ return sle;
+}
+
+int open_socket(sle)
+ struct sock_list *sle;
+{
+ sle->fd = socket(AF_INET, sle->type, sle->protocol);
+ if (sle->fd < 0) {
+ perror("socket");
+ return -1;
+ }
+ if (sle->type != SOCK_RAW) {
+#if 0
+ printf("binding fd %d to %s:%d\n", sle->fd,
+ inet_ntoa(sle->addr.sin_addr), ntohs(sle->addr.sin_port));
+#endif
+ if (bind(sle->fd, (struct sockaddr *)&sle->addr, sizeof(sle->addr))<0){
+ perror("bind");
+ close(sle->fd);
+ return -1;
+ }
+ }
+ return sle->fd;
+}
+
+int main(argc, argv)
+ int argc;
+ char *argv[];
+{
+ struct sock_list *sl = NULL, *sltmp = NULL;
+ int count = 0;
+ int c;
+ char *run_prog = NULL;
+
+ while ((c = getopt(argc, argv, "s:d:r:p:")) != EOF)
+ switch (c) {
+ case 's':
+ sltmp = new_entry(SOCK_STREAM, optarg);
+ if (!sltmp) {
+ exit(1);
+ }
+ sltmp->next = sl;
+ sl = sltmp;
+ count++;
+ break;
+ case 'd':
+ sltmp = new_entry(SOCK_DGRAM, optarg);
+ if (!sltmp) {
+ exit(1);
+ }
+ sltmp->next = sl;
+ sl = sltmp;
+ count++;
+ break;
+ case 'r':
+ sltmp = new_entry(SOCK_RAW, optarg);
+ if (!sltmp) {
+ exit(1);
+ }
+ sltmp->next = sl;
+ sl = sltmp;
+ count++;
+ break;
+ case 'p':
+ run_prog = optarg;
+ break;
+ default:
+ exit(1);
+ }
+ argc -= optind;
+ argv += optind;
+
+ for(sltmp = sl; sltmp != NULL; sltmp = sltmp->next)
+ if (open_socket(sltmp) < 0) {
+ fprintf(stderr, "failed to create socket!\n");
+ exit(1);
+ }
+
+ setuid(getuid());
+
+ {
+ int i;
+ char **newargv;
+ char *run_prog_name;
+
+ newargv = (char **)malloc((1 + 2*count + argc + 1) * sizeof(char*));
+
+ if ((run_prog_name = strrchr(run_prog, (int)'/')) == NULL)
+ run_prog_name = run_prog;
+ else
+ run_prog_name++;
+
+ i = 0;
+ newargv[i++] = run_prog_name;
+
+ for (; argc; argc--, argv++, i++)
+ newargv[i] = *argv;
+ for(sltmp = sl; sltmp != NULL; ) {
+ char *fd_str = (char *)malloc(8);
+ if (!fd_str) exit(1);
+ sprintf(fd_str, "%d", sltmp->fd);
+ if (sltmp->arg && *(sltmp->arg))
+ newargv[i++] = sltmp->arg;
+ newargv[i++] = fd_str;
+ sl = sltmp;
+ sltmp = sltmp->next;
+ free(sl);
+ }
+ newargv[i] = (char *)NULL;
+ execv(run_prog, newargv);
+ perror("exec");
+ exit(1);
+ }
+ exit(0);
+}
diff --git a/lib/inets/test/inets_sup_SUITE.erl b/lib/inets/test/inets_sup_SUITE.erl
index 0ac940fd3e..5b8b1463c8 100644
--- a/lib/inets/test/inets_sup_SUITE.erl
+++ b/lib/inets/test/inets_sup_SUITE.erl
@@ -1,18 +1,19 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2004-2013. All Rights Reserved.
+%% Copyright Ericsson AB 2004-2016. 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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% 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.
+%% http://www.apache.org/licenses/LICENSE-2.0
+%%
+%% Unless required by applicable law or agreed to in writing, software
+%% distributed under the License is distributed on an "AS IS" BASIS,
+%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+%% See the License for the specific language governing permissions and
+%% limitations under the License.
%%
%% %CopyrightEnd%
%%
@@ -21,15 +22,18 @@
-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).
-suite() -> [{ct_hooks,[ts_install_cth]}].
+suite() ->
+ [{ct_hooks,[ts_install_cth]},
+ {timetrap,{seconds, 10}}
+ ].
all() ->
- [default_tree, ftpc_worker, tftpd_worker, httpd_subtree,
+ [default_tree, ftpc_worker, tftpd_worker,
+ httpd_subtree, httpd_subtree_profile,
httpc_subtree].
groups() ->
@@ -41,149 +45,83 @@ init_per_group(_GroupName, 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) ->
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(_) ->
inets:stop(),
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(httpd_subtree, Config) ->
- io:format("init_per_testcase(httpd_subtree) -> entry with"
- "~n Config: ~p"
- "~n", [Config]),
- Dog = test_server:timetrap(?t:minutes(1)),
- NewConfig = lists:keydelete(watchdog, 1, Config),
-
- DataDir = ?config(data_dir, Config),
- PrivDir = ?config(priv_dir, Config),
- ServerROOT = filename:join(PrivDir, "server_root"),
- DocROOT = filename:join(PrivDir, "htdocs"),
- ConfDir = filename:join(ServerROOT, "conf"),
-
- io:format("init_per_testcase(httpd_subtree) -> create dir(s)"
- "~n", []),
- file:make_dir(ServerROOT), %% until http_test is cleaned up!
- ok = file:make_dir(DocROOT),
- ok = file:make_dir(ConfDir),
-
- io:format("init_per_testcase(httpd_subtree) -> copy file(s)"
- "~n", []),
- {ok, _} = inets_test_lib:copy_file("simple.conf", DataDir, PrivDir),
- {ok, _} = inets_test_lib:copy_file("mime.types", DataDir, ConfDir),
-
- io:format("init_per_testcase(httpd_subtree) -> write file(s)"
- "~n", []),
- ConfFile = filename:join(PrivDir, "simple.conf"),
- {ok, Fd} = file:open(ConfFile, [append]),
- ok = file:write(Fd, "ServerRoot " ++ ServerROOT ++ "\n"),
- ok = file:write(Fd, "DocumentRoot " ++ DocROOT ++ "\n"),
- ok = file:close(Fd),
-
- %% To make sure application:set_env is not overwritten by any
- %% app-file settings.
- io:format("init_per_testcase(httpd_subtree) -> load inets app"
- "~n", []),
- application:load(inets),
- io:format("init_per_testcase(httpd_subtree) -> update inets env"
- "~n", []),
- ok = application:set_env(inets, services, [{httpd, ConfFile}]),
-
+ PrivDir = proplists:get_value(priv_dir, Config),
+ Dir = filename:join(PrivDir, "root"),
+ ok = file:make_dir(Dir),
+
+ SimpleConfig = [{port, 0},
+ {server_name,"www.test"},
+ {modules, [mod_get]},
+ {server_root, Dir},
+ {document_root, Dir},
+ {bind_address, any},
+ {ipfamily, inet}],
try
- io:format("init_per_testcase(httpd_subtree) -> start inets app"
- "~n", []),
- ok = inets:start(),
- io:format("init_per_testcase(httpd_subtree) -> done"
- "~n", []),
- [{watchdog, Dog}, {server_root, ServerROOT}, {doc_root, DocROOT},
- {conf_dir, ConfDir}| NewConfig]
+ inets:stop(),
+ inets:start(),
+ inets:start(httpd, SimpleConfig),
+ Config
catch
_:Reason ->
- io:format("init_per_testcase(httpd_subtree) -> "
- "failed starting inets - cleanup"
- "~n Reason: ~p"
- "~n", [Reason]),
- application:unset_env(inets, services),
- application:unload(inets),
+ inets:stop(),
exit({failed_starting_inets, Reason})
end;
-
-init_per_testcase(Case, Config) ->
- io:format("init_per_testcase(~p) -> entry with"
- "~n Config: ~p"
- "~n", [Case, Config]),
- Dog = test_server:timetrap(?t:minutes(5)),
- NewConfig = lists:keydelete(watchdog, 1, Config),
- Stop = inets:stop(),
- io:format("init_per_testcase(~p) -> Stop: ~p"
- "~n", [Case, Stop]),
+init_per_testcase(httpd_subtree_profile, Config) ->
+ PrivDir = proplists:get_value(priv_dir, Config),
+ Dir = filename:join(PrivDir, "root"),
+ ok = file:make_dir(Dir),
+
+ SimpleConfig = [{port, 0},
+ {server_name,"www.test"},
+ {modules, [mod_get]},
+ {server_root, Dir},
+ {document_root, Dir},
+ {bind_address, any},
+ {profile, test_profile},
+ {ipfamily, inet}],
+ try
+ inets:stop(),
+ inets:start(),
+ {ok, _} = inets:start(httpd, SimpleConfig),
+ Config
+ catch
+ _:Reason ->
+ inets:stop(),
+ exit({failed_starting_inets, Reason})
+ end;
+
+
+init_per_testcase(_Case, Config) ->
+ inets:stop(),
ok = inets:start(),
- [{watchdog, Dog} | NewConfig].
-
-
-%%--------------------------------------------------------------------
-%% 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(httpd_subtree, Config) ->
- Dog = ?config(watchdog, Config),
- test_server:timetrap_cancel(Dog),
- PrivDir = ?config(priv_dir, Config),
- inets_test_lib:del_dirs(PrivDir),
+ Config.
+
+end_per_testcase(Case, Config) when Case == httpd_subtree;
+ Case == httpd_subtree_profile ->
+ PrivDir = proplists:get_value(priv_dir, Config),
+ Dir = filename:join(PrivDir, "root"),
+ inets_test_lib:del_dirs(Dir),
ok;
-end_per_testcase(_, Config) ->
- Dog = ?config(watchdog, Config),
- test_server:timetrap_cancel(Dog),
+end_per_testcase(_, _) ->
inets:stop(),
ok.
%%-------------------------------------------------------------------------
%% Test cases starts here.
%%-------------------------------------------------------------------------
-
-
-%%-------------------------------------------------------------------------
-%% default_tree
-%%-------------------------------------------------------------------------
-default_tree(doc) ->
- ["Makes sure the correct processes are started and linked,"
- "in the default case."];
-default_tree(suite) ->
- [];
+default_tree() ->
+ [{doc, "Makes sure the correct processes are started and linked,"
+ "in the default case."}].
default_tree(Config) when is_list(Config) ->
TopSupChildren = supervisor:which_children(inets_sup),
4 = length(TopSupChildren),
@@ -216,94 +154,111 @@ default_tree(Config) when is_list(Config) ->
ok.
-
-%%-------------------------------------------------------------------------
-%% ftpc_worker
-%%-------------------------------------------------------------------------
-ftpc_worker(doc) ->
- ["Makes sure the ftp worker processes are added and removed "
- "appropriatly to/from the supervison tree."];
-ftpc_worker(suite) ->
- [];
-ftpc_worker(Config) when is_list(Config) ->
+ftpc_worker() ->
+ [{doc, "Makes sure the ftp worker processes are added and removed "
+ "appropriatly to/from the supervison tree."}].
+ftpc_worker(Config0) when is_list(Config0) ->
[] = supervisor:which_children(ftp_sup),
- try
- begin
- {_Tag, FtpdHost} = ftp_suite_lib:dirty_select_ftpd_host(Config),
- case inets:start(ftpc, [{host, FtpdHost}]) of
- {ok, Pid} ->
- case supervisor:which_children(ftp_sup) of
- [{_,_, worker, [ftp]}] ->
- inets:stop(ftpc, Pid),
- test_server:sleep(5000),
- [] = supervisor:which_children(ftp_sup),
- ok;
- Children ->
- exit({unexpected_children, Children})
- end;
- _ ->
- {skip, "Unable to reach test FTP server"}
+ case ftp_SUITE:init_per_suite(Config0) of
+ {skip, _} = Skip ->
+ Skip;
+ Config ->
+ FtpdHost = proplists:get_value(ftpd_host,Config),
+ {ok, Pid} = inets:start(ftpc, [{host, FtpdHost}]),
+ case supervisor:which_children(ftp_sup) of
+ [{_,_, worker, [ftp]}] ->
+ inets:stop(ftpc, Pid),
+ ct:sleep(5000),
+ [] = supervisor:which_children(ftp_sup),
+ catch ftp_SUITE:end_per_SUITE(Config),
+ ok;
+ Children ->
+ catch ftp_SUITE:end_per_SUITE(Config),
+ exit({unexpected_children, Children})
end
- end
- catch
- throw:{error, not_found} ->
- {skip, "No available FTP servers"}
end.
-
-%%-------------------------------------------------------------------------
-%% tftpd_worker
-%%-------------------------------------------------------------------------
-tftpd_worker(doc) ->
- ["Makes sure the tftp sub tree is correct."];
-tftpd_worker(suite) ->
- [];
+tftpd_worker() ->
+ [{doc, "Makes sure the tftp sub tree is correct."}].
tftpd_worker(Config) when is_list(Config) ->
[] = supervisor:which_children(tftp_sup),
- {ok, Pid0} = inets:start(tftpd, [{host, "localhost"},
- {port, inet_port()}]),
- {ok, _Pid1} = inets:start(tftpd, [{host, "localhost"},
- {port, inet_port()}], stand_alone),
+ {ok, Pid0} = inets:start(tftpd, [{host, inets_test_lib:hostname()},
+ {port, 0}]),
+ {ok, _Pid1} = inets:start(tftpd, [{host, inets_test_lib:hostname()},
+ {port, 0}], stand_alone),
[{_,Pid0, worker, _}] = supervisor:which_children(tftp_sup),
inets:stop(tftpd, Pid0),
- test_server:sleep(5000),
+ ct:sleep(5000),
[] = supervisor:which_children(tftp_sup),
ok.
+httpd_subtree() ->
+ [{doc, "Makes sure the httpd sub tree is correct."}].
+httpd_subtree(Config) when is_list(Config) ->
+ do_httpd_subtree(Config, default).
+
+httpd_subtree_profile(doc) ->
+ ["Makes sure the httpd sub tree is correct when using a profile"];
+httpd_subtree_profile(Config) when is_list(Config) ->
+ do_httpd_subtree(Config, test_profile).
+
+httpc_subtree() ->
+ [{doc, "Makes sure the httpd sub tree is correct."}].
+httpc_subtree(Config) when is_list(Config) ->
+ {ok, Foo} = inets:start(httpc, [{profile, foo}]),
+
+ {ok, Bar} = inets:start(httpc, [{profile, bar}], stand_alone),
+
+ HttpcChildren = supervisor:which_children(httpc_profile_sup),
+
+ {value, {httpc_manager, _, worker, [httpc_manager]}} =
+ lists:keysearch(httpc_manager, 1, HttpcChildren),
+
+ {value,{{httpc,foo}, _Pid, worker, [httpc_manager]}} =
+ lists:keysearch({httpc, foo}, 1, HttpcChildren),
+ false = lists:keysearch({httpc, bar}, 1, HttpcChildren),
+
+ inets:stop(httpc, Foo),
+ exit(Bar, normal).
%%-------------------------------------------------------------------------
-%% httpd_subtree
+%% Internal functions
%%-------------------------------------------------------------------------
-httpd_subtree(doc) ->
- ["Makes sure the httpd sub tree is correct."];
-httpd_subtree(suite) ->
- [];
-httpd_subtree(Config) when is_list(Config) ->
- io:format("httpd_subtree -> entry with"
- "~n Config: ~p"
- "~n", [Config]),
- %% Check that we have the httpd top supervisor
- io:format("httpd_subtree -> verify inets~n", []),
+verify_child(Parent, Child, Type) ->
+ Children = supervisor:which_children(Parent),
+ verify_child(Children, Parent, Child, Type).
+
+verify_child([], Parent, Child, _Type) ->
+ {error, {child_not_found, Child, Parent}};
+verify_child([{Id, _Pid, Type2, Mods}|Children], Parent, Child, Type) ->
+ case lists:member(Child, Mods) of
+ true when (Type2 =:= Type) ->
+ {ok, Id};
+ true when (Type2 =/= Type) ->
+ {error, {wrong_type, Type2, Child, Parent}};
+ false ->
+ verify_child(Children, Parent, Child, Type)
+ end.
+
+do_httpd_subtree(_Config, Profile) ->
+ %% Check that we have the httpd top supervisor
{ok, _} = verify_child(inets_sup, httpd_sup, supervisor),
%% Check that we have the httpd instance supervisor
- io:format("httpd_subtree -> verify httpd~n", []),
{ok, Id} = verify_child(httpd_sup, httpd_instance_sup, supervisor),
- {httpd_instance_sup, Addr, Port} = Id,
- Instance = httpd_util:make_name("httpd_instance_sup", Addr, Port),
+ {httpd_instance_sup, Addr, Port, Profile} = Id,
+ Instance = httpd_util:make_name("httpd_instance_sup", Addr, Port, Profile),
%% 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, Profile),
case supervisor:which_children(InstanceAcc) of
[_ | _] ->
ok;
@@ -314,7 +269,7 @@ httpd_subtree(Config) when is_list(Config) ->
%% Check that the httpd instance misc supervisor has no children
io:format("httpd_subtree -> verify misc~n", []),
- InstanceMisc = httpd_util:make_name("httpd_misc_sup", Addr, Port),
+ InstanceMisc = httpd_util:make_name("httpd_misc_sup", Addr, Port, Profile),
case supervisor:which_children(InstanceMisc) of
[] ->
ok;
@@ -324,90 +279,3 @@ httpd_subtree(Config) when is_list(Config) ->
end,
io:format("httpd_subtree -> done~n", []),
ok.
-
-
-verify_child(Parent, Child, Type) ->
-%% io:format("verify_child -> entry with"
-%% "~n Parent: ~p"
-%% "~n Child: ~p"
-%% "~n Type: ~p"
-%% "~n", [Parent, Child, Type]),
- Children = supervisor:which_children(Parent),
-%% io:format("verify_child -> which children"
-%% "~n Children: ~p"
-%% "~n", [Children]),
- verify_child(Children, Parent, Child, Type).
-
-verify_child([], Parent, Child, _Type) ->
- {error, {child_not_found, Child, Parent}};
-verify_child([{Id, _Pid, Type2, Mods}|Children], Parent, Child, Type) ->
- case lists:member(Child, Mods) of
- true when (Type2 =:= Type) ->
-%% io:format("verify_child -> found with expected type"
-%% "~n Id: ~p"
-%% "~n", [Id]),
- {ok, Id};
- true when (Type2 =/= Type) ->
-%% io:format("verify_child -> found with unexpected type"
-%% "~n Type2: ~p"
-%% "~n Id: ~p"
-%% "~n", [Type2, Id]),
- {error, {wrong_type, Type2, Child, Parent}};
- false ->
- verify_child(Children, Parent, Child, Type)
- end.
-
-
-
-%%-------------------------------------------------------------------------
-%% httpc_subtree
-%%-------------------------------------------------------------------------
-httpc_subtree(doc) ->
- ["Makes sure the httpc sub tree is correct."];
-httpc_subtree(suite) ->
- [];
-httpc_subtree(Config) when is_list(Config) ->
- tsp("httpc_subtree -> entry with"
- "~n Config: ~p", [Config]),
-
- tsp("httpc_subtree -> start inets service httpc with profile foo"),
- {ok, _Foo} = inets:start(httpc, [{profile, foo}]),
-
- tsp("httpc_subtree -> "
- "start stand-alone inets service httpc with profile bar"),
- {ok, _Bar} = inets:start(httpc, [{profile, bar}], stand_alone),
-
- tsp("httpc_subtree -> retreive list of httpc instances"),
- HttpcChildren = supervisor:which_children(httpc_profile_sup),
- tsp("httpc_subtree -> HttpcChildren: ~n~p", [HttpcChildren]),
-
- tsp("httpc_subtree -> verify httpc stand-alone instances"),
- {value, {httpc_manager, _, worker, [httpc_manager]}} =
- lists:keysearch(httpc_manager, 1, HttpcChildren),
-
- tsp("httpc_subtree -> verify httpc (named) instances"),
- {value,{{httpc,foo}, Pid, worker, [httpc_manager]}} =
- lists:keysearch({httpc, foo}, 1, HttpcChildren),
- false = lists:keysearch({httpc, bar}, 1, HttpcChildren),
-
- tsp("httpc_subtree -> stop inets"),
- inets:stop(httpc, Pid),
-
- tsp("httpc_subtree -> done"),
- ok.
-
-inet_port() ->
- {ok, Socket} = gen_tcp:listen(0, [{reuseaddr, true}]),
- {ok, Port} = inet:port(Socket),
- gen_tcp:close(Socket),
- Port.
-
-
-tsp(F) ->
- tsp(F, []).
-tsp(F, A) ->
- test_server:format("~p ~p:" ++ F ++ "~n", [self(), ?MODULE | A]).
-
-tsf(Reason) ->
- test_server:fail(Reason).
-
diff --git a/lib/inets/test/inets_sup_SUITE_data/mime.types b/lib/inets/test/inets_sup_SUITE_data/mime.types
deleted file mode 100644
index e52d345ff7..0000000000
--- a/lib/inets/test/inets_sup_SUITE_data/mime.types
+++ /dev/null
@@ -1,3 +0,0 @@
-# MIME type Extension
-text/html html htm
-text/plain asc txt
diff --git a/lib/inets/test/inets_sup_SUITE_data/simple.conf b/lib/inets/test/inets_sup_SUITE_data/simple.conf
deleted file mode 100644
index e1429b4a28..0000000000
--- a/lib/inets/test/inets_sup_SUITE_data/simple.conf
+++ /dev/null
@@ -1,6 +0,0 @@
-Port 8888
-ServerName www.test
-SocketType ip_comm
-Modules mod_get
-ServerAdmin [email protected]
-
diff --git a/lib/inets/test/inets_test_lib.erl b/lib/inets/test/inets_test_lib.erl
index 6ccc7b0da1..f1185f7574 100644
--- a/lib/inets/test/inets_test_lib.erl
+++ b/lib/inets/test/inets_test_lib.erl
@@ -1,18 +1,19 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2001-2013. All Rights Reserved.
+%% Copyright Ericsson AB 2001-2015. 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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% 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.
+%% http://www.apache.org/licenses/LICENSE-2.0
+%%
+%% Unless required by applicable law or agreed to in writing, software
+%% distributed under the License is distributed on an "AS IS" BASIS,
+%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+%% See the License for the specific language governing permissions and
+%% limitations under the License.
%%
%% %CopyrightEnd%
%%
@@ -287,7 +288,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(_, []) -> [].
@@ -496,13 +499,6 @@ close(essl,Socket) ->
close(ip_comm,Socket) ->
catch gen_tcp:close(Socket).
-millis() ->
- erlang:now().
-
-millis_diff(A,B) ->
- T1 = (element(1,A)*1000000) + element(2,A) + (element(3,A)/1000000),
- T2 = (element(1,B)*1000000) + element(2,B) + (element(3,B)/1000000),
- T1 - T2.
hours(N) -> trunc(N * 1000 * 60 * 60).
minutes(N) -> trunc(N * 1000 * 60).
@@ -544,31 +540,19 @@ flush() ->
tsp(F) ->
tsp(F, []).
tsp(F, A) ->
- Timestamp = formated_timestamp(),
- test_server:format("*** ~s ~p ~p " ++ F ++ "~n",
+ Timestamp = inets_lib:formated_timestamp(),
+ 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().
-formated_timestamp() ->
- format_timestamp( os:timestamp() ).
-
-format_timestamp({_N1, _N2, N3} = Now) ->
- {Date, Time} = calendar:now_to_datetime(Now),
- {YYYY,MM,DD} = Date,
- {Hour,Min,Sec} = Time,
- FormatDate =
- io_lib:format("~.4w:~.2.0w:~.2.0w ~.2.0w:~.2.0w:~.2.0w 4~w",
- [YYYY,MM,DD,Hour,Min,Sec,round(N3/1000)]),
- lists:flatten(FormatDate).
-
start_apps(Apps) ->
lists:foreach(fun(App) ->
application:stop(App),
@@ -579,3 +563,12 @@ stop_apps(Apps) ->
application:stop(App)
end, Apps).
+inet_port(Node) ->
+ {Port, Socket} = do_inet_port(Node),
+ rpc:call(Node, gen_tcp, close, [Socket]),
+ Port.
+
+do_inet_port(Node) ->
+ {ok, Socket} = rpc:call(Node, gen_tcp, listen, [0, [{reuseaddr, true}]]),
+ {ok, Port} = rpc:call(Node, inet, port, [Socket]),
+ {Port, Socket}.
diff --git a/lib/inets/test/inets_test_lib.hrl b/lib/inets/test/inets_test_lib.hrl
index 6a86b1b764..d436395290 100644
--- a/lib/inets/test/inets_test_lib.hrl
+++ b/lib/inets/test/inets_test_lib.hrl
@@ -1,18 +1,19 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2001-2011. All Rights Reserved.
+%% Copyright Ericsson AB 2001-2016. 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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% 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.
+%% http://www.apache.org/licenses/LICENSE-2.0
+%%
+%% Unless required by applicable law or agreed to in writing, software
+%% distributed under the License is distributed on an "AS IS" BASIS,
+%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+%% See the License for the specific language governing permissions and
+%% limitations under the License.
%%
%% %CopyrightEnd%
%%
@@ -20,96 +21,8 @@
%%----------------------------------------------------------------------
%% Purpose: Define common macros for testing
%%----------------------------------------------------------------------
-
-%% - Print macros -
-
--ifdef(inets_debug).
--define(DEBUG(F,A), inets_test_lib:debug(F, A, ?MODULE, ?LINE)).
--else.
--define(DEBUG(F,A),ok).
--endif.
-
--ifdef(inets_log).
--define(LOG(F,A), inets_test_lib:log(F, A, ?MODULE, ?LINE)).
--else.
--define(LOG(F,A),ok).
--endif.
-
--define(INFO(F,A), inets_test_lib:info(F, A, ?MODULE, ?LINE)).
--define(PRINT(F,A), inets_test_lib:print(F, A, ?MODULE, ?LINE)).
-
-
-%% - Macros stolen from the test server -
-
--ifndef(line).
--define(line,put(test_server_loc,{?MODULE,?LINE}),).
--endif.
-
-
-%% - OS Command and stuff
-
--define(OSCMD(Cmd), inets_test_lib:oscmd(Cmd)).
-
--define(PRINT_SYSTEM_INFO(P), inets_test_lib:print_system_info(P)).
-
--define(RUN_ON_OS(OS, FUN), inets_test_lib:run_on_os(OS, FUN)).
--define(RUN_ON_WINDOWS(FUN), inets_test_lib:run_on_windows(FUN)).
-
-
-%% - Test case macros -
-
--define(EXPANDABLE(I, C, F), inets_test_lib:expandable(I, C, F)).
--define(OS_BASED_SKIP(Skippable),
- inets_test_lib:os_based_skip(Skippable)).
-
--define(NON_PC_TC_MAYBE_SKIP(Config, Condition),
- inets_test_lib:non_pc_tc_maybe_skip(Config, Condition, ?MODULE, ?LINE)).
-
-
-
%% - Misc macros -
-define(ENSURE_STARTED(A), inets_test_lib:ensure_started(A)).
--define(UPDATE(K,V,C), inets_test_lib:update_config(K,V,C)).
--define(CONFIG(K,C), inets_test_lib:get_config(K,C)).
--define(HOSTNAME(), inets_test_lib:hostname()).
--define(SZ(X), inets_test_lib:sz(X)).
-
-
-%% - Test case macros -
-
--define(SKIP(Reason), inets_test_lib:skip(Reason, ?MODULE, ?LINE)).
--define(FAIL(Reason), inets_test_lib:fail(Reason, ?MODULE, ?LINE)).
-
-
-%% - Socket macros -
-
--define(CONNECT(M,H,P), inets_test_lib:connect(M,H,P)).
--define(SEND(M,S,D), inets_test_lib:send(M,S,D)).
--define(CSEND(M,S,D,C,T), inets_test_lib:csend(M,S,D,C,T)).
--define(CLOSE(M,S), inets_test_lib:close(M,S)).
-
-
-%% - Time macros -
-
--define(HOURS(N), inets_test_lib:hours(N)).
--define(MINS(N), inets_test_lib:minutes(N)).
--define(SECS(N), inets_test_lib:seconds(N)).
-
--define(WD_START(T), inets_test_lib:watchdog_start(T)).
--define(WD_STOP(P), inets_test_lib:watchdog_stop(P)).
-
--define(SLEEP(MSEC), inets_test_lib:sleep(MSEC)).
--define(M(), inets_test_lib:millis()).
--define(MDIFF(A,B), inets_test_lib:millis_diff(A,B)).
-
-
-%% - Process utility macros -
-
--define(FLUSH(), inets_test_lib:flush_mqueue()).
--define(ETRAP_GET(), inets_test_lib:trap_exit()).
--define(ETRAP_SET(O), inets_test_lib:trap_exit(O)).
-
-
diff --git a/lib/inets/test/old_httpd_SUITE.erl b/lib/inets/test/old_httpd_SUITE.erl
new file mode 100644
index 0000000000..172db53844
--- /dev/null
+++ b/lib/inets/test/old_httpd_SUITE.erl
@@ -0,0 +1,2347 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2005-2016. All Rights Reserved.
+%%
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
+%%
+%% http://www.apache.org/licenses/LICENSE-2.0
+%%
+%% Unless required by applicable law or agreed to in writing, software
+%% distributed under the License is distributed on an "AS IS" BASIS,
+%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+%% See the License for the specific language governing permissions and
+%% limitations under the License.
+%%
+%% %CopyrightEnd%
+%%
+%%
+
+-module(old_httpd_SUITE).
+
+-include_lib("common_test/include/ct.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,
+ %% Only used through load_config
+ %% but we still need these tests
+ %% should be cleaned up and moved to new test suite
+ %%ip_restart_no_block,
+ %%ip_restart_disturbing_block,
+ %%ip_restart_non_disturbing_block,
+ %% Tested in inets_SUITE
+ %%ip_block_disturbing_idle,
+ %%ip_block_non_disturbing_idle,
+ ip_block_503
+ %% Tested in new httpd_SUITE
+ %%ip_block_disturbing_active,
+ %%ip_block_non_disturbing_active,
+ %%ip_block_disturbing_blocker_dies,
+ %%ip_block_non_disturbing_blocker_dies
+ %% No longer relevant
+ %%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,
+ ]},
+ {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
+ %% Replaced by load_config
+ %% 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]),
+
+ PrivDir = proplists:get_value(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 = proplists:get_value(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 = proplists:get_value(data_dir, Config),
+ SuiteTopDir = proplists:get_value(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 = proplists:get_value(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(proplists:get_value(node, Config)),
+ [{watchdog, Dog} | NewConfig];
+ "mod_htaccess" ->
+ ServerRoot = proplists:get_value(server_root, Config),
+ Path = filename:join([ServerRoot, "htdocs"]),
+ catch remove_htaccess(Path),
+ create_htaccess_data(Path, proplists:get_value(address, Config)),
+ [{watchdog, Dog} | NewConfig];
+ "range" ->
+ ServerRoot = proplists:get_value(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 = proplists:get_value(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,
+ proplists:get_value(host, Config), proplists:get_value(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,
+ proplists:get_value(host, Config), proplists:get_value(node, Config)),
+ ok.
+
+%%-------------------------------------------------------------------------
+ip_mod_security(doc) ->
+ ["Module test: mod_security"];
+ip_mod_security(suite) ->
+ [];
+ip_mod_security(Config) when is_list(Config) ->
+ ServerRoot = proplists:get_value(server_root, Config),
+ httpd_mod:security(ServerRoot, ip_comm, ?IP_PORT,
+ proplists:get_value(host, Config), proplists:get_value(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,
+ proplists:get_value(host, Config), proplists:get_value(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 = proplists:get_value(server_root, Config),
+ Host = proplists:get_value(host, Config),
+ Node = proplists:get_value(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,
+ proplists:get_value(host, Config), proplists:get_value(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,
+ proplists:get_value(host, Config), proplists:get_value(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,
+ proplists:get_value(host, Config), proplists:get_value(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,
+ proplists:get_value(host, Config), proplists:get_value(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,
+ proplists:get_value(host, Config), proplists:get_value(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,
+ proplists:get_value(host, Config), proplists:get_value(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,
+ proplists:get_value(host, Config), proplists:get_value(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, proplists:get_value(host, Config),
+ proplists:get_value(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, proplists:get_value(host, Config),
+ proplists:get_value(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, proplists:get_value(host, Config),
+ proplists:get_value(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, proplists:get_value(host, Config),
+ proplists:get_value(node, Config), ?MAX_HEADER_SIZE),
+ ok.
+
+
+%%-------------------------------------------------------------------------
+ip_time_test(doc) ->
+ [""];
+ip_time_test(suite) ->
+ [];
+ip_time_test(Config) when is_list(Config) ->
+ httpd_time_test:t(ip_comm, proplists:get_value(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, proplists:get_value(host, Config),
+ proplists:get_value(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,
+ proplists:get_value(host, Config),
+ proplists:get_value(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,
+ proplists:get_value(host, Config),
+ proplists:get_value(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,
+ proplists:get_value(host, Config),
+ proplists:get_value(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,
+ proplists:get_value(host, Config),
+ proplists:get_value(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,
+ proplists:get_value(host,
+ Config),
+ proplists:get_value(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,
+ proplists:get_value(host,
+ Config),
+ proplists:get_value(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,
+ proplists:get_value(host,
+ Config),
+ proplists:get_value(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,
+ proplists:get_value(host,
+ Config),
+ proplists:get_value(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,
+ proplists:get_value(host, Config),
+ proplists:get_value(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,
+ proplists:get_value(host, Config),
+ proplists:get_value(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, proplists:get_value(host, Config),
+ proplists:get_value(node, Config)),
+ ok.
+%%-------------------------------------------------------------------------
+ip_restart_disturbing_block(doc) ->
+ [""];
+ip_restart_disturbing_block(suite) ->
+ [];
+ip_restart_disturbing_block(Config) when is_list(Config) ->
+ httpd_block:restart_disturbing_block(ip_comm, ?IP_PORT,
+ proplists:get_value(host, Config),
+ proplists:get_value(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) ->
+ httpd_block:restart_non_disturbing_block(ip_comm, ?IP_PORT,
+ proplists:get_value(host, Config),
+ proplists:get_value(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,
+ proplists:get_value(host, Config), proplists:get_value(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,
+ proplists:get_value(host, Config),
+ proplists:get_value(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 = proplists:get_value(server_root, Config),
+ httpd_mod:security(ServerRoot,
+ Tag,
+ ?SSL_PORT,
+ proplists:get_value(host, Config),
+ proplists:get_value(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,
+ proplists:get_value(host, Config),
+ proplists:get_value(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 = proplists:get_value(server_root, Config),
+ Host = proplists:get_value(host, Config),
+ Node = proplists:get_value(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,
+ proplists:get_value(host, Config),
+ proplists:get_value(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,
+ proplists:get_value(host, Config),
+ proplists:get_value(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,
+ proplists:get_value(host, Config),
+ proplists:get_value(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,
+ proplists:get_value(host, Config),
+ proplists:get_value(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,
+ proplists:get_value(host, Config),
+ proplists:get_value(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,
+ proplists:get_value(host, Config),
+ proplists:get_value(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,
+ proplists:get_value(host, Config),
+ proplists:get_value(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,
+ proplists:get_value(host, Config),
+ proplists:get_value(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) ->
+ httpd_load:load_test(Tag,
+ ?SSL_PORT,
+ proplists:get_value(host, Config),
+ proplists:get_value(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) ->
+ httpd_load:load_test(Tag,
+ ?SSL_PORT,
+ proplists:get_value(host, Config),
+ proplists:get_value(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,
+ proplists:get_value(host, Config),
+ proplists:get_value(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) ->
+ httpd_time_test:t(Tag,
+ proplists:get_value(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,
+ proplists:get_value(host, Config),
+ proplists:get_value(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,
+ proplists:get_value(host, Config),
+ proplists:get_value(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,
+ proplists:get_value(host, Config),
+ proplists:get_value(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,
+ proplists:get_value(host, Config),
+ proplists:get_value(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,
+ proplists:get_value(host, Config),
+ proplists:get_value(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 = proplists:get_value(host, Config),
+ Node = proplists:get_value(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 = proplists:get_value(host, Config),
+ Node = proplists:get_value(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 = proplists:get_value(host, Config),
+ Node = proplists:get_value(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 = proplists:get_value(host, Config),
+ Node = proplists:get_value(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,
+ proplists:get_value(host, Config),
+ proplists:get_value(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,
+ proplists:get_value(host, Config),
+ proplists:get_value(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,
+ proplists:get_value(host, Config),
+ proplists:get_value(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) ->
+ httpd_block:restart_disturbing_block(Tag, ?SSL_PORT,
+ proplists:get_value(host, Config),
+ proplists:get_value(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) ->
+ httpd_block:restart_non_disturbing_block(Tag,
+ ?SSL_PORT,
+ proplists:get_value(host, Config),
+ proplists:get_value(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, proplists:get_value(host, Config),
+ proplists:get_value(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, proplists:get_value(host, Config),
+ proplists:get_value(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, proplists:get_value(host, Config),
+ proplists:get_value(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, proplists:get_value(host, Config),
+ proplists:get_value(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 = proplists:get_value(server_root, Config),
+ DocRoot = filename:join([ServerRoot, "htdocs"]),
+ httpd_1_1:if_test(ip_comm, ?IP_PORT, proplists:get_value(host, Config),
+ proplists:get_value(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, proplists:get_value(host, Config),
+ proplists:get_value(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, proplists:get_value(host, Config),
+ proplists:get_value(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 = proplists:get_value(host, Config),
+ Node = proplists:get_value(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 = proplists:get_value(host, Config),
+ Node = proplists:get_value(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 = proplists:get_value(host, Config),
+ Node = proplists:get_value(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 = proplists:get_value(host, Config),
+ Node = proplists:get_value(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 = proplists:get_value(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,
+ proplists:get_value(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 = proplists:get_value(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 = proplists:get_value(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, proplists:get_value(host, Config),
+ ?IP_PORT, proplists:get_value(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) ->
+ ct:skip(as_of_r15_behaviour_of_calendar_has_changed),
+ Host = proplists:get_value(host,Config),
+ ServerRoot = proplists:get_value(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, proplists:get_value(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, proplists:get_value(host, Config),
+ ?IP_PORT, proplists:get_value(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, proplists:get_value(host, Config),
+ ?IP_PORT, proplists:get_value(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, proplists:get_value(host, Config),
+ ?IP_PORT, proplists:get_value(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 = proplists:get_value(server_root, Config),
+ TcTopDir = proplists:get_value(tc_top_dir, Config),
+ Port = proplists:get_value(port, Config),
+ Type = proplists:get_value(sock_type, Config),
+ Host = proplists:get_value(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_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_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 = proplists:get_value(server_root, Config),
+ TcTopDir = proplists:get_value(tc_top_dir, Config),
+ Port = proplists:get_value(port, Config),
+ SockType = proplists:get_value(sock_type, Config),
+ Mods = io_lib:format("~p", [httpd_mod]),
+ Funcs = io_lib:format("~p", [ssl_password_cb]),
+ Host = proplists:get_value(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_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..ed4d63a3bb 100644
--- a/lib/inets/test/httpd_SUITE_data/server_root/Makefile
+++ b/lib/inets/test/old_httpd_SUITE_data/server_root/Makefile
@@ -1,18 +1,19 @@
#
# %CopyrightBegin%
#
-# Copyright Ericsson AB 1997-2010. All Rights Reserved.
+# Copyright Ericsson AB 1997-2016. 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/.
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
#
-# 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.
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
#
# %CopyrightEnd%
#
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..7b1b4a15b2 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
@@ -1,7 +1,7 @@
Port 8080
#ServerName your.server.net
SocketType ip_comm
-Modules mod_alias mod_auth mod_esi mod_actions mod_cgi mod_include mod_dir mod_get mod_head mod_log mod_disk_log
+Modules mod_alias mod_auth mod_esi mod_actions mod_cgi mod_dir mod_get mod_head mod_log mod_disk_log
ServerAdmin [email protected]
ServerRoot /var/tmp/server_root
ErrorLog logs/error_log_8080
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..042779fcd0 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
@@ -1,7 +1,7 @@
Port 8888
#ServerName your.server.net
SocketType ip_comm
-Modules mod_alias mod_auth mod_esi mod_actions mod_cgi mod_include mod_dir mod_get mod_head mod_log mod_disk_log
+Modules mod_alias mod_auth mod_esi mod_actions mod_cgi mod_dir mod_get mod_head mod_log mod_disk_log
ServerAdmin [email protected]
ServerRoot /var/tmp/server_root
ErrorLog logs/error_log_8888
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..3f9fde03b5 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
@@ -1,18 +1,19 @@
#
# %CopyrightBegin%
#
-# Copyright Ericsson AB 1997-2011. All Rights Reserved.
+# Copyright Ericsson AB 1997-2016. 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.
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
#
# %CopyrightEnd%
#
@@ -63,7 +64,7 @@ SocketType ip_comm
# WARNING! Do not tamper with this directive unless you are familiar with
# EWSAPI.
-Modules mod_alias mod_auth mod_esi mod_actions mod_cgi mod_responsecontrol mod_trace mod_range mod_head mod_include mod_dir mod_get mod_log mod_disk_log
+Modules mod_alias mod_auth mod_esi mod_actions mod_cgi mod_responsecontrol mod_trace mod_range mod_head mod_dir mod_get mod_log mod_disk_log
# ServerAdmin: Your address, where problems with the server should be
# e-mailed.
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..de49ceafd0 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
@@ -1,7 +1,7 @@
Port 8088
#ServerName your.server.net
SocketType ssl
-Modules mod_alias mod_auth mod_esi mod_actions mod_cgi mod_include mod_dir mod_get mod_head mod_log mod_disk_log
+Modules mod_alias mod_auth mod_esi mod_actions mod_cgi mod_dir mod_get mod_head mod_log mod_disk_log
ServerAdmin [email protected]
ServerRoot /var/tmp/server_root
ErrorLog logs/error_log_8088
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
new file mode 100644
index 0000000000..bb23d971f4
--- /dev/null
+++ b/lib/inets/test/old_httpd_SUITE_data/server_root/icons/a.gif
Binary files differ
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
new file mode 100644
index 0000000000..eaecd2172a
--- /dev/null
+++ b/lib/inets/test/old_httpd_SUITE_data/server_root/icons/alert.black.gif
Binary files differ
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
new file mode 100644
index 0000000000..a423894043
--- /dev/null
+++ b/lib/inets/test/old_httpd_SUITE_data/server_root/icons/alert.red.gif
Binary files differ
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
new file mode 100644
index 0000000000..3a1c139fc4
--- /dev/null
+++ b/lib/inets/test/old_httpd_SUITE_data/server_root/icons/apache_pb.gif
Binary files differ
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
new file mode 100644
index 0000000000..a694ae1ec3
--- /dev/null
+++ b/lib/inets/test/old_httpd_SUITE_data/server_root/icons/back.gif
Binary files differ
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
new file mode 100644
index 0000000000..eb84268c4c
--- /dev/null
+++ b/lib/inets/test/old_httpd_SUITE_data/server_root/icons/ball.gray.gif
Binary files differ
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
new file mode 100644
index 0000000000..a8425cb574
--- /dev/null
+++ b/lib/inets/test/old_httpd_SUITE_data/server_root/icons/ball.red.gif
Binary files differ
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
new file mode 100644
index 0000000000..9a15cbae04
--- /dev/null
+++ b/lib/inets/test/old_httpd_SUITE_data/server_root/icons/binary.gif
Binary files differ
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
new file mode 100644
index 0000000000..62d0363108
--- /dev/null
+++ b/lib/inets/test/old_httpd_SUITE_data/server_root/icons/binhex.gif
Binary files differ
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
new file mode 100644
index 0000000000..0ccf01e198
--- /dev/null
+++ b/lib/inets/test/old_httpd_SUITE_data/server_root/icons/blank.gif
Binary files differ
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
new file mode 100644
index 0000000000..270fdb1c06
--- /dev/null
+++ b/lib/inets/test/old_httpd_SUITE_data/server_root/icons/bomb.gif
Binary files differ
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
new file mode 100644
index 0000000000..65dcd002ea
--- /dev/null
+++ b/lib/inets/test/old_httpd_SUITE_data/server_root/icons/box1.gif
Binary files differ
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
new file mode 100644
index 0000000000..c43bc4faec
--- /dev/null
+++ b/lib/inets/test/old_httpd_SUITE_data/server_root/icons/box2.gif
Binary files differ
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
new file mode 100644
index 0000000000..9f8cbe9f76
--- /dev/null
+++ b/lib/inets/test/old_httpd_SUITE_data/server_root/icons/broken.gif
Binary files differ
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
new file mode 100644
index 0000000000..fbdcf575f7
--- /dev/null
+++ b/lib/inets/test/old_httpd_SUITE_data/server_root/icons/burst.gif
Binary files differ
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
new file mode 100644
index 0000000000..eb97cb7333
--- /dev/null
+++ b/lib/inets/test/old_httpd_SUITE_data/server_root/icons/button1.gif
Binary files differ
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
new file mode 100644
index 0000000000..fe0c97998c
--- /dev/null
+++ b/lib/inets/test/old_httpd_SUITE_data/server_root/icons/button10.gif
Binary files differ
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
new file mode 100644
index 0000000000..7698455bf9
--- /dev/null
+++ b/lib/inets/test/old_httpd_SUITE_data/server_root/icons/button2.gif
Binary files differ
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
new file mode 100644
index 0000000000..a8b8319232
--- /dev/null
+++ b/lib/inets/test/old_httpd_SUITE_data/server_root/icons/button3.gif
Binary files differ
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
new file mode 100644
index 0000000000..0fd15a0d7f
--- /dev/null
+++ b/lib/inets/test/old_httpd_SUITE_data/server_root/icons/button4.gif
Binary files differ
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
new file mode 100644
index 0000000000..64241e5c5d
--- /dev/null
+++ b/lib/inets/test/old_httpd_SUITE_data/server_root/icons/button5.gif
Binary files differ
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
new file mode 100644
index 0000000000..867cfd1212
--- /dev/null
+++ b/lib/inets/test/old_httpd_SUITE_data/server_root/icons/button6.gif
Binary files differ
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
new file mode 100644
index 0000000000..b3f5fb248f
--- /dev/null
+++ b/lib/inets/test/old_httpd_SUITE_data/server_root/icons/button7.gif
Binary files differ
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
new file mode 100644
index 0000000000..7a308be8f6
--- /dev/null
+++ b/lib/inets/test/old_httpd_SUITE_data/server_root/icons/button8.gif
Binary files differ
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
new file mode 100644
index 0000000000..9acba576c0
--- /dev/null
+++ b/lib/inets/test/old_httpd_SUITE_data/server_root/icons/button9.gif
Binary files differ
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
new file mode 100644
index 0000000000..3883088e7a
--- /dev/null
+++ b/lib/inets/test/old_httpd_SUITE_data/server_root/icons/buttonl.gif
Binary files differ
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
new file mode 100644
index 0000000000..c4dc3887db
--- /dev/null
+++ b/lib/inets/test/old_httpd_SUITE_data/server_root/icons/buttonr.gif
Binary files differ
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
new file mode 100644
index 0000000000..7555b6c164
--- /dev/null
+++ b/lib/inets/test/old_httpd_SUITE_data/server_root/icons/c.gif
Binary files differ
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
new file mode 100644
index 0000000000..f8d76a8c23
--- /dev/null
+++ b/lib/inets/test/old_httpd_SUITE_data/server_root/icons/comp.blue.gif
Binary files differ
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
new file mode 100644
index 0000000000..7664cd0364
--- /dev/null
+++ b/lib/inets/test/old_httpd_SUITE_data/server_root/icons/comp.gray.gif
Binary files differ
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
new file mode 100644
index 0000000000..39e732739f
--- /dev/null
+++ b/lib/inets/test/old_httpd_SUITE_data/server_root/icons/compressed.gif
Binary files differ
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
new file mode 100644
index 0000000000..b0ffb7e0cc
--- /dev/null
+++ b/lib/inets/test/old_httpd_SUITE_data/server_root/icons/continued.gif
Binary files differ
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
new file mode 100644
index 0000000000..48264601ae
--- /dev/null
+++ b/lib/inets/test/old_httpd_SUITE_data/server_root/icons/dir.gif
Binary files differ
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
new file mode 100644
index 0000000000..a354c871cd
--- /dev/null
+++ b/lib/inets/test/old_httpd_SUITE_data/server_root/icons/down.gif
Binary files differ
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
new file mode 100644
index 0000000000..791be33105
--- /dev/null
+++ b/lib/inets/test/old_httpd_SUITE_data/server_root/icons/dvi.gif
Binary files differ
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
new file mode 100644
index 0000000000..fbe353c282
--- /dev/null
+++ b/lib/inets/test/old_httpd_SUITE_data/server_root/icons/f.gif
Binary files differ
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
new file mode 100644
index 0000000000..48264601ae
--- /dev/null
+++ b/lib/inets/test/old_httpd_SUITE_data/server_root/icons/folder.gif
Binary files differ
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
new file mode 100644
index 0000000000..30979cb528
--- /dev/null
+++ b/lib/inets/test/old_httpd_SUITE_data/server_root/icons/folder.open.gif
Binary files differ
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
new file mode 100644
index 0000000000..75332d9e59
--- /dev/null
+++ b/lib/inets/test/old_httpd_SUITE_data/server_root/icons/folder.sec.gif
Binary files differ
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
new file mode 100644
index 0000000000..b2959b4c85
--- /dev/null
+++ b/lib/inets/test/old_httpd_SUITE_data/server_root/icons/forward.gif
Binary files differ
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
new file mode 100644
index 0000000000..de60b2940f
--- /dev/null
+++ b/lib/inets/test/old_httpd_SUITE_data/server_root/icons/generic.gif
Binary files differ
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
new file mode 100644
index 0000000000..94743981d9
--- /dev/null
+++ b/lib/inets/test/old_httpd_SUITE_data/server_root/icons/generic.red.gif
Binary files differ
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
new file mode 100644
index 0000000000..88d5240c3c
--- /dev/null
+++ b/lib/inets/test/old_httpd_SUITE_data/server_root/icons/generic.sec.gif
Binary files differ
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
new file mode 100644
index 0000000000..5cdbc7206d
--- /dev/null
+++ b/lib/inets/test/old_httpd_SUITE_data/server_root/icons/hand.right.gif
Binary files differ
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
new file mode 100644
index 0000000000..85a5d68317
--- /dev/null
+++ b/lib/inets/test/old_httpd_SUITE_data/server_root/icons/hand.up.gif
Binary files differ
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
new file mode 100644
index 0000000000..35443fb63a
--- /dev/null
+++ b/lib/inets/test/old_httpd_SUITE_data/server_root/icons/htdig.gif
Binary files differ
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
new file mode 100644
index 0000000000..ad1686e448
--- /dev/null
+++ b/lib/inets/test/old_httpd_SUITE_data/server_root/icons/icon.sheet.gif
Binary files differ
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
new file mode 100644
index 0000000000..01e442bfa9
--- /dev/null
+++ b/lib/inets/test/old_httpd_SUITE_data/server_root/icons/image1.gif
Binary files differ
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
new file mode 100644
index 0000000000..751faeea36
--- /dev/null
+++ b/lib/inets/test/old_httpd_SUITE_data/server_root/icons/image2.gif
Binary files differ
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
new file mode 100644
index 0000000000..4f30484ff6
--- /dev/null
+++ b/lib/inets/test/old_httpd_SUITE_data/server_root/icons/image3.gif
Binary files differ
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
new file mode 100644
index 0000000000..162478fb3a
--- /dev/null
+++ b/lib/inets/test/old_httpd_SUITE_data/server_root/icons/index.gif
Binary files differ
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
new file mode 100644
index 0000000000..c96338a152
--- /dev/null
+++ b/lib/inets/test/old_httpd_SUITE_data/server_root/icons/layout.gif
Binary files differ
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
new file mode 100644
index 0000000000..279e6710d4
--- /dev/null
+++ b/lib/inets/test/old_httpd_SUITE_data/server_root/icons/left.gif
Binary files differ
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
new file mode 100644
index 0000000000..c5b6889a76
--- /dev/null
+++ b/lib/inets/test/old_httpd_SUITE_data/server_root/icons/link.gif
Binary files differ
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
new file mode 100644
index 0000000000..0035183774
--- /dev/null
+++ b/lib/inets/test/old_httpd_SUITE_data/server_root/icons/movie.gif
Binary files differ
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
new file mode 100644
index 0000000000..7b917b4e91
--- /dev/null
+++ b/lib/inets/test/old_httpd_SUITE_data/server_root/icons/p.gif
Binary files differ
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
new file mode 100644
index 0000000000..39bc90e795
--- /dev/null
+++ b/lib/inets/test/old_httpd_SUITE_data/server_root/icons/patch.gif
Binary files differ
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
new file mode 100644
index 0000000000..c88fd777c4
--- /dev/null
+++ b/lib/inets/test/old_httpd_SUITE_data/server_root/icons/pdf.gif
Binary files differ
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
new file mode 100644
index 0000000000..6f7a0ae7a7
--- /dev/null
+++ b/lib/inets/test/old_httpd_SUITE_data/server_root/icons/pie0.gif
Binary files differ
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
new file mode 100644
index 0000000000..03aa6be71e
--- /dev/null
+++ b/lib/inets/test/old_httpd_SUITE_data/server_root/icons/pie1.gif
Binary files differ
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
new file mode 100644
index 0000000000..b04c5e0908
--- /dev/null
+++ b/lib/inets/test/old_httpd_SUITE_data/server_root/icons/pie2.gif
Binary files differ
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
new file mode 100644
index 0000000000..4db9d023ed
--- /dev/null
+++ b/lib/inets/test/old_httpd_SUITE_data/server_root/icons/pie3.gif
Binary files differ
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
new file mode 100644
index 0000000000..93471fdd88
--- /dev/null
+++ b/lib/inets/test/old_httpd_SUITE_data/server_root/icons/pie4.gif
Binary files differ
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
new file mode 100644
index 0000000000..57aee93f07
--- /dev/null
+++ b/lib/inets/test/old_httpd_SUITE_data/server_root/icons/pie5.gif
Binary files differ
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
new file mode 100644
index 0000000000..0dc327b569
--- /dev/null
+++ b/lib/inets/test/old_httpd_SUITE_data/server_root/icons/pie6.gif
Binary files differ
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
new file mode 100644
index 0000000000..8661337f06
--- /dev/null
+++ b/lib/inets/test/old_httpd_SUITE_data/server_root/icons/pie7.gif
Binary files differ
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
new file mode 100644
index 0000000000..59ddb34ce0
--- /dev/null
+++ b/lib/inets/test/old_httpd_SUITE_data/server_root/icons/pie8.gif
Binary files differ
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
new file mode 100644
index 0000000000..0e6e506e00
--- /dev/null
+++ b/lib/inets/test/old_httpd_SUITE_data/server_root/icons/portal.gif
Binary files differ
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
new file mode 100644
index 0000000000..d324ab80ea
--- /dev/null
+++ b/lib/inets/test/old_httpd_SUITE_data/server_root/icons/poweredby.gif
Binary files differ
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
new file mode 100644
index 0000000000..0f565bc1db
--- /dev/null
+++ b/lib/inets/test/old_httpd_SUITE_data/server_root/icons/ps.gif
Binary files differ
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
new file mode 100644
index 0000000000..818a5cdc7e
--- /dev/null
+++ b/lib/inets/test/old_httpd_SUITE_data/server_root/icons/quill.gif
Binary files differ
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
new file mode 100644
index 0000000000..b256e5f75f
--- /dev/null
+++ b/lib/inets/test/old_httpd_SUITE_data/server_root/icons/right.gif
Binary files differ
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
new file mode 100644
index 0000000000..af6ba2b097
--- /dev/null
+++ b/lib/inets/test/old_httpd_SUITE_data/server_root/icons/screw1.gif
Binary files differ
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
new file mode 100644
index 0000000000..06dccb3e44
--- /dev/null
+++ b/lib/inets/test/old_httpd_SUITE_data/server_root/icons/screw2.gif
Binary files differ
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
new file mode 100644
index 0000000000..d8a853bc58
--- /dev/null
+++ b/lib/inets/test/old_httpd_SUITE_data/server_root/icons/script.gif
Binary files differ
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
new file mode 100644
index 0000000000..8efb49f55d
--- /dev/null
+++ b/lib/inets/test/old_httpd_SUITE_data/server_root/icons/sound1.gif
Binary files differ
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
new file mode 100644
index 0000000000..48e6a7fb2f
--- /dev/null
+++ b/lib/inets/test/old_httpd_SUITE_data/server_root/icons/sound2.gif
Binary files differ
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
new file mode 100644
index 0000000000..7067070da2
--- /dev/null
+++ b/lib/inets/test/old_httpd_SUITE_data/server_root/icons/sphere1.gif
Binary files differ
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
new file mode 100644
index 0000000000..a9e462a377
--- /dev/null
+++ b/lib/inets/test/old_httpd_SUITE_data/server_root/icons/sphere2.gif
Binary files differ
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
new file mode 100644
index 0000000000..4cfe0a5e0f
--- /dev/null
+++ b/lib/inets/test/old_httpd_SUITE_data/server_root/icons/star.gif
Binary files differ
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
new file mode 100644
index 0000000000..a0c83cb85b
--- /dev/null
+++ b/lib/inets/test/old_httpd_SUITE_data/server_root/icons/star_blank.gif
Binary files differ
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
new file mode 100644
index 0000000000..617e779efa
--- /dev/null
+++ b/lib/inets/test/old_httpd_SUITE_data/server_root/icons/tar.gif
Binary files differ
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
new file mode 100644
index 0000000000..45e43233b8
--- /dev/null
+++ b/lib/inets/test/old_httpd_SUITE_data/server_root/icons/tex.gif
Binary files differ
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
new file mode 100644
index 0000000000..4c623909fb
--- /dev/null
+++ b/lib/inets/test/old_httpd_SUITE_data/server_root/icons/text.gif
Binary files differ
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
new file mode 100644
index 0000000000..33697dbb66
--- /dev/null
+++ b/lib/inets/test/old_httpd_SUITE_data/server_root/icons/transfer.gif
Binary files differ
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
new file mode 100644
index 0000000000..32b1ea23fb
--- /dev/null
+++ b/lib/inets/test/old_httpd_SUITE_data/server_root/icons/unknown.gif
Binary files differ
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
new file mode 100644
index 0000000000..6d6d6d1ebf
--- /dev/null
+++ b/lib/inets/test/old_httpd_SUITE_data/server_root/icons/up.gif
Binary files differ
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
new file mode 100644
index 0000000000..4387d529f6
--- /dev/null
+++ b/lib/inets/test/old_httpd_SUITE_data/server_root/icons/uu.gif
Binary files differ
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
new file mode 100644
index 0000000000..4387d529f6
--- /dev/null
+++ b/lib/inets/test/old_httpd_SUITE_data/server_root/icons/uuencoded.gif
Binary files differ
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
new file mode 100644
index 0000000000..05b4ec2058
--- /dev/null
+++ b/lib/inets/test/old_httpd_SUITE_data/server_root/icons/world1.gif
Binary files differ
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
new file mode 100644
index 0000000000..e3203f7a88
--- /dev/null
+++ b/lib/inets/test/old_httpd_SUITE_data/server_root/icons/world2.gif
Binary files differ
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/old_httpd_SUITE_data/server_root/ssl/ssl_client.pem b/lib/inets/test/old_httpd_SUITE_data/server_root/ssl/ssl_client.pem
new file mode 100644
index 0000000000..427447958d
--- /dev/null
+++ b/lib/inets/test/old_httpd_SUITE_data/server_root/ssl/ssl_client.pem
@@ -0,0 +1,31 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIICXQIBAAKBgQCTFBPkOO98fDY3j6MIxIGKp+rampfIay50Lx4+EnCnRSSVwC+n
+0VVmP7V5SGFJpuXJzN0hvqPUWOOjiMTNlNRaGy0pqu2oMXWAPLOxHWL1wT53h2Zr
+3FUNU/N0Rvnkttse1KZJ9uYCLKUiuXXsv2rR62nH3OhRIiBHSAcSv0NRWwIDAQAB
+AoGACdIVYe/LTeydUihtInC8lZ2QuPgJmoBNocRjqJFipEihoL4scHAx25n1bBvB
+I0HZphffzBkGp28oBAtl2LRPWXqu527unc/RWRfLMqSK1xNSq1DxD1a30zkrZPna
+QiV65vEJuNSJTtlDy/Zqc/BVZXCpxWlzYQedZgkmf0Qse8ECQQCmaz02Yur8zC9f
+eSQKU5OSzGw3bSIumEzziCfHdTheK6MEoccf5TCAyLXhZwA7QlKja4tFXfeyVxws
+/LlnUJN9AkEA4j+xnOeYUyGKXL5i+BAbnqpI4MzPiq+IoCYkaRlD/wAws24r5HNI
+ZQmEHWqD/NNzOf/A2XuyLtMiTGJPW/DftwJBAKKpJP6Ytuh6xz8BUCnLwO12Y7vV
+LtjuQiCzD3aUa5EYA9HOMqxJPxxRkf0LyR0i2VUkE8+sZiPpov+R0cJa7p0CQQCj
+40GUiArGRSiF7/+e84QeVfl+pb29F1QftiFv5DZmFEwy3Z572KpbTh5edJbxYHY6
+UDHxGHJFCvnwXNJhpkVXAkBJqfEfiMJ3Q/E5Gpf3sQizacouW92iiN8ojlF1oB80
+t34RysJH7SgI3gdMhTribCo2UUaV0StjR6yodPN+TB2J
+-----END RSA PRIVATE KEY-----
+-----BEGIN CERTIFICATE-----
+MIIChzCCAfCgAwIBAgIGAIsapa8BMA0GCSqGSIb3DQEBBQUAMHoxDjAMBgNVBAMT
+BW90cENBMSAwHgYJKoZIhvcNAQkBFhF0ZXN0ZXJAZXJsYW5nLm9yZzESMBAGA1UE
+BxMJU3RvY2tob2xtMQswCQYDVQQGEwJTRTEPMA0GA1UEChMGZXJsYW5nMRQwEgYD
+VQQLEwt0ZXN0aW5nIGRlcDAiGA8yMDEwMDkwMTAwMDAwMFoYDzIwMjUwODI4MDAw
+MDAwWjB7MQ8wDQYDVQQDEwZjbGllbnQxIDAeBgkqhkiG9w0BCQEWEXRlc3RlckBl
+cmxhbmcub3JnMRIwEAYDVQQHEwlTdG9ja2hvbG0xCzAJBgNVBAYTAlNFMQ8wDQYD
+VQQKEwZlcmxhbmcxFDASBgNVBAsTC3Rlc3RpbmcgZGVwMIGfMA0GCSqGSIb3DQEB
+AQUAA4GNADCBiQKBgQCTFBPkOO98fDY3j6MIxIGKp+rampfIay50Lx4+EnCnRSSV
+wC+n0VVmP7V5SGFJpuXJzN0hvqPUWOOjiMTNlNRaGy0pqu2oMXWAPLOxHWL1wT53
+h2Zr3FUNU/N0Rvnkttse1KZJ9uYCLKUiuXXsv2rR62nH3OhRIiBHSAcSv0NRWwID
+AQABoxMwETAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEBBQUAA4GBAG8t6f1A
+PF7xayGxtUpG2r6W5ETylC3ZIKPS2kfJk9aYi7AZNTp7/xTU6SgqvFBN8aBPzxCD
+4jHrSNC8DSb4X1x9uimarb6qdZDHEdij+DRAd2eygJHZxEf7+8B4Fx34thQeU9hZ
+S1Izke5AlsyFMkvB7h0anE4k9BfuU70vl6v5
+-----END CERTIFICATE-----
diff --git a/lib/inets/test/old_httpd_SUITE_data/server_root/ssl/ssl_server.pem b/lib/inets/test/old_httpd_SUITE_data/server_root/ssl/ssl_server.pem
new file mode 100644
index 0000000000..4aac86db49
--- /dev/null
+++ b/lib/inets/test/old_httpd_SUITE_data/server_root/ssl/ssl_server.pem
@@ -0,0 +1,31 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIICXQIBAAKBgQCf4Htxr99lLs5W8QQw7jdakqyAkIjOW4aqH8sr4va4SvZ9Adq6
+7k8jMHefCVZo+F8x4cwsBgB4aWzFIGBnvFTi6YsH27XW7f9O9IPCej8fdhRZ4UAt
+NHa253buOWpDGla2JmIdkmfFvXFJycMIKbG5tYilVXoWKBMKmCwWaXz0nQIDAQAB
+AoGAQIlma0r6W6bcRj4+Wd4fXCFvHuq5Psu1fYEeC5Yvz8761xVjjSfbrDHJZ9pm
+FjOEgedK+s5lbDXqYVyjbdyZSugStBRocSmbG8SQHcAsxR2ZIkNzX2hYzB+lslWo
+T3YJojDyB134O7XJznCu+ZFXP86jyJ1JT6k6a+OIHcwnJ+ECQQDYn57dY4Px3mEd
+VBLStN3YkRF5oFyT+xk7IaKeLLB6n4gCnoVbBoHut7PFbPYPzoNzEwPk3MQKDIHb
+Kig3S5CpAkEAvPA1VmoJWAlN6kUi+F2L8HXEArzE8x7vwdsslrwMKUe4dFS+ZC/7
+5iDOaxcZ7TYkCgwzBt341++DCgP6j3fY1QJBALB6AcOcwi52m6l4B8mu3ZkEPjdX
+BHTuONTqhv/TqoaLlxODL2NDvvDKqeMp7KBd/srt79swW2lQXS4+fvrlTdkCQQCm
+zxj4O1QWkthkfje6ubSkTwUIOatUzrp1F9GNH2dJRtX2dx9FCwxGCC7WY6XzRXqa
+GF0wsedSllbGD+82nWQlAkAicMGqCqRq4hKR/cVmFatOqKVWCVkx6OFF2FhuiI5Z
+h5eIOPGCt8dVRs1P9DNSld/D98Sfm65m85z8BtXovvYV
+-----END RSA PRIVATE KEY-----
+-----BEGIN CERTIFICATE-----
+MIIChzCCAfCgAwIBAgIGANUxXM9BMA0GCSqGSIb3DQEBBQUAMHoxDjAMBgNVBAMT
+BW90cENBMSAwHgYJKoZIhvcNAQkBFhF0ZXN0ZXJAZXJsYW5nLm9yZzESMBAGA1UE
+BxMJU3RvY2tob2xtMQswCQYDVQQGEwJTRTEPMA0GA1UEChMGZXJsYW5nMRQwEgYD
+VQQLEwt0ZXN0aW5nIGRlcDAiGA8yMDEwMDkwMTAwMDAwMFoYDzIwMjUwODI4MDAw
+MDAwWjB7MQ8wDQYDVQQDEwZzZXJ2ZXIxIDAeBgkqhkiG9w0BCQEWEXRlc3RlckBl
+cmxhbmcub3JnMRIwEAYDVQQHEwlTdG9ja2hvbG0xCzAJBgNVBAYTAlNFMQ8wDQYD
+VQQKEwZlcmxhbmcxFDASBgNVBAsTC3Rlc3RpbmcgZGVwMIGfMA0GCSqGSIb3DQEB
+AQUAA4GNADCBiQKBgQCf4Htxr99lLs5W8QQw7jdakqyAkIjOW4aqH8sr4va4SvZ9
+Adq67k8jMHefCVZo+F8x4cwsBgB4aWzFIGBnvFTi6YsH27XW7f9O9IPCej8fdhRZ
+4UAtNHa253buOWpDGla2JmIdkmfFvXFJycMIKbG5tYilVXoWKBMKmCwWaXz0nQID
+AQABoxMwETAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEBBQUAA4GBAGF5Pfwk
+QDdwJup/mVITPxbBls4Yl7anDooUQsq8066lA1g54H/PRfXscGkyCFGh1ifXvf1L
+psMRoBAdDHL/wSJplk3rRavkC94eBgnTFZmfKL6844g1j53yameiYL8IEVExYMBg
+/XGyc0qwq57WT8B/K4aElrvlBlQ0wF3wN54M
+-----END CERTIFICATE-----
diff --git a/lib/inets/test/property_test/README b/lib/inets/test/property_test/README
new file mode 100644
index 0000000000..57602bf719
--- /dev/null
+++ b/lib/inets/test/property_test/README
@@ -0,0 +1,12 @@
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%%% %%%
+%%% WARNING %%%
+%%% %%%
+%%% This is experimental code which may be changed or removed %%%
+%%% anytime without any warning. %%%
+%%% %%%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+The test in this directory are written assuming that the user has a QuickCheck license. They are to be run manually. Some may be possible to be run with other tools, e.g. PropEr.
+
diff --git a/lib/inets/test/property_test/ftp_simple_client_server.erl b/lib/inets/test/property_test/ftp_simple_client_server.erl
new file mode 100644
index 0000000000..c98d87b514
--- /dev/null
+++ b/lib/inets/test/property_test/ftp_simple_client_server.erl
@@ -0,0 +1,307 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2004-2016. All Rights Reserved.
+%%
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
+%%
+%% http://www.apache.org/licenses/LICENSE-2.0
+%%
+%% Unless required by applicable law or agreed to in writing, software
+%% distributed under the License is distributed on an "AS IS" BASIS,
+%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+%% See the License for the specific language governing permissions and
+%% limitations under the License.
+%%
+%% %CopyrightEnd%
+%%
+%%
+
+-module(ftp_simple_client_server).
+
+-compile(export_all).
+
+-ifndef(EQC).
+-ifndef(PROPER).
+-define(EQC,true).
+%%-define(PROPER,true).
+-endif.
+-endif.
+
+
+-ifdef(EQC).
+
+-include_lib("eqc/include/eqc.hrl").
+-include_lib("eqc/include/eqc_statem.hrl").
+-define(MOD_eqc, eqc).
+-define(MOD_eqc_gen, eqc_gen).
+-define(MOD_eqc_statem, eqc_statem).
+
+-else.
+-ifdef(PROPER).
+
+-include_lib("proper/include/proper.hrl").
+-define(MOD_eqc, proper).
+-define(MOD_eqc_gen, proper_gen).
+-define(MOD_eqc_statem, proper_statem).
+
+-endif.
+-endif.
+
+-record(state, {
+ initialized = false,
+ priv_dir,
+ data_dir,
+ servers = [], % [ {IP,Port,Userid,Pwd} ]
+ clients = [], % [ client_ref() ]
+ store = [] % [ {Name,Contents} ]
+ }).
+
+-define(fmt(F,A), io:format(F,A)).
+%%-define(fmt(F,A), ok).
+
+-define(v(K,L), proplists:get_value(K,L)).
+
+%%%================================================================
+%%%
+%%% Properties
+%%%
+
+%% This function is for normal eqc calls:
+prop_ftp() ->
+ {ok,PWD} = file:get_cwd(),
+ prop_ftp(filename:join([PWD,?MODULE_STRING++"_data"]),
+ filename:join([PWD,?MODULE_STRING,"_files"])).
+
+%% This function is for calls from common_test test cases:
+prop_ftp(Config) ->
+ prop_ftp(filename:join([?v(property_dir,Config), ?MODULE_STRING++"_data"]),
+ ?v(priv_dir,Config) ).
+
+
+prop_ftp(DataDir, PrivDir) ->
+ S0 = #state{data_dir = DataDir,
+ priv_dir = PrivDir},
+ ?FORALL(Cmds, more_commands(10,commands(?MODULE,S0)),
+ aggregate(command_names(Cmds),
+ begin {_H,S,Result} = run_commands(?MODULE,Cmds),
+ % io:format('**** Result=~p~n',[Result]),
+ % io:format('**** S=~p~n',[S]),
+ % io:format('**** _H=~p~n',[_H]),
+ % io:format('**** Cmds=~p~n',[Cmds]),
+ [cmnd_stop_server(X) || X <- S#state.servers],
+ [inets:stop(ftpc,X) || {ok,X} <- S#state.clients],
+ Result==ok
+ end)
+ ).
+
+%%%================================================================
+%%%
+%%% State model
+%%%
+
+%% @doc Returns the state in which each test case starts. (Unless a different
+%% initial state is supplied explicitly to, e.g. commands/2.)
+-spec initial_state() ->?MOD_eqc_statem:symbolic_state().
+initial_state() ->
+ ?fmt("Initial_state()~n",[]),
+ #state{}.
+
+%% @doc Command generator, S is the current state
+-spec command(S :: ?MOD_eqc_statem:symbolic_state()) -> ?MOD_eqc_gen:gen(eqc_statem:call()).
+
+command(#state{initialized=false,
+ priv_dir=PrivDir}) ->
+ {call,?MODULE,cmnd_init,[PrivDir]};
+
+command(#state{servers=[],
+ priv_dir=PrivDir,
+ data_dir=DataDir}) ->
+ {call,?MODULE,cmnd_start_server,[PrivDir,DataDir]};
+
+command(#state{servers=Ss=[_|_],
+ clients=[]}) ->
+ {call,?MODULE,cmnd_start_client,[oneof(Ss)]};
+
+command(#state{servers=Ss=[_|_],
+ clients=Cs=[_|_],
+ store=Store=[_|_]
+ }) ->
+ frequency([
+ { 5, {call,?MODULE,cmnd_start_client,[oneof(Ss)]}},
+ { 5, {call,?MODULE,cmnd_stop_client,[oneof(Cs)]}},
+ {10, {call,?MODULE,cmnd_put,[oneof(Cs),file_path(),file_contents()]}},
+ {20, {call,?MODULE,cmnd_get,[oneof(Cs),oneof(Store)]}},
+ {10, {call,?MODULE,cmnd_delete,[oneof(Cs),oneof(Store)]}}
+ ]);
+
+command(#state{servers=Ss=[_|_],
+ clients=Cs=[_|_],
+ store=[]
+ }) ->
+ frequency([
+ {5, {call,?MODULE,cmnd_start_client,[oneof(Ss)]}},
+ {5, {call,?MODULE,cmnd_stop_client,[oneof(Cs)]}},
+ {10, {call,?MODULE,cmnd_put,[oneof(Cs),file_path(),file_contents()]}}
+ ]).
+
+%% @doc Precondition, checked before command is added to the command sequence.
+-spec precondition(S :: ?MOD_eqc_statem:symbolic_state(), C :: ?MOD_eqc_statem:call()) -> boolean().
+
+precondition(#state{clients=Cs}, {call, _, cmnd_put, [C,_,_]}) -> lists:member(C,Cs);
+
+precondition(#state{clients=Cs, store=Store},
+ {call, _, cmnd_get, [C,X]}) -> lists:member(C,Cs) andalso lists:member(X,Store);
+
+precondition(#state{clients=Cs, store=Store},
+ {call, _, cmnd_delete, [C,X]}) -> lists:member(C,Cs) andalso lists:member(X,Store);
+
+precondition(#state{servers=Ss}, {call, _, cmnd_start_client, _}) -> Ss =/= [];
+
+precondition(#state{clients=Cs}, {call, _, cmnd_stop_client, [C]}) -> lists:member(C,Cs);
+
+precondition(#state{initialized=IsInit}, {call, _, cmnd_init, _}) -> IsInit==false;
+
+precondition(_S, {call, _, _, _}) -> true.
+
+
+%% @doc Postcondition, checked after command has been evaluated
+%% Note: S is the state before next_state(S,_,C)
+-spec postcondition(S :: ?MOD_eqc_statem:dynamic_state(), C :: ?MOD_eqc_statem:call(),
+ Res :: term()) -> boolean().
+
+postcondition(_S, {call, _, cmnd_get, [_,{_Name,Expected}]}, {ok,Value}) ->
+ Value == Expected;
+
+postcondition(S, {call, _, cmnd_delete, [_,{Name,_Expected}]}, ok) ->
+ ?fmt("file:read_file(..) = ~p~n",[file:read_file(filename:join(S#state.priv_dir,Name))]),
+ {error,enoent} == file:read_file(filename:join(S#state.priv_dir,Name));
+
+postcondition(S, {call, _, cmnd_put, [_,Name,Value]}, ok) ->
+ {ok,Bin} = file:read_file(filename:join(S#state.priv_dir,Name)),
+ Bin == unicode:characters_to_binary(Value);
+
+postcondition(_S, {call, _, cmnd_stop_client, _}, ok) -> true;
+
+postcondition(_S, {call, _, cmnd_start_client, _}, {ok,_}) -> true;
+
+postcondition(_S, {call, _, cmnd_init, _}, ok) -> true;
+
+postcondition(_S, {call, _, cmnd_start_server, _}, {ok,_}) -> true.
+
+
+%% @doc Next state transformation, S is the current state. Returns next state.
+-spec next_state(S :: ?MOD_eqc_statem:symbolic_state(),
+ V :: ?MOD_eqc_statem:var(),
+ C :: ?MOD_eqc_statem:call()) -> ?MOD_eqc_statem:symbolic_state().
+
+next_state(S, _V, {call, _, cmnd_put, [_,Name,Val]}) ->
+ S#state{store = [{Name,Val} | lists:keydelete(Name,1,S#state.store)]};
+
+next_state(S, _V, {call, _, cmnd_delete, [_,{Name,_Val}]}) ->
+ S#state{store = lists:keydelete(Name,1,S#state.store)};
+
+next_state(S, V, {call, _, cmnd_start_client, _}) ->
+ S#state{clients = [V | S#state.clients]};
+
+next_state(S, V, {call, _, cmnd_start_server, _}) ->
+ S#state{servers = [V | S#state.servers]};
+
+next_state(S, _V, {call, _, cmnd_stop_client, [C]}) ->
+ S#state{clients = S#state.clients -- [C]};
+
+next_state(S, _V, {call, _, cmnd_init, _}) ->
+ S#state{initialized=true};
+
+next_state(S, _V, {call, _, _, _}) ->
+ S.
+
+%%%================================================================
+%%%
+%%% Data model
+%%%
+
+file_path() -> non_empty(list(alphanum_char())).
+%%file_path() -> non_empty( list(oneof([alphanum_char(), utf8_char()])) ).
+
+%%file_contents() -> list(alphanum_char()).
+file_contents() -> list(oneof([alphanum_char(), utf8_char()])).
+
+alphanum_char() -> oneof(lists:seq($a,$z) ++ lists:seq($A,$Z) ++ lists:seq($0,$9)).
+
+utf8_char() -> oneof("åäöÅÄÖ話话カタカナひらがな").
+
+%%%================================================================
+%%%
+%%% Commands doing something with the System Under Test
+%%%
+
+cmnd_init(PrivDir) ->
+ ?fmt('Call cmnd_init(~p)~n',[PrivDir]),
+ os:cmd("killall vsftpd"),
+ clear_files(PrivDir),
+ ok.
+
+cmnd_start_server(PrivDir, DataDir) ->
+ ?fmt('Call cmnd_start_server(~p, ~p)~n',[PrivDir,DataDir]),
+ Cmnd = ["vsftpd ", filename:join(DataDir,"vsftpd.conf"),
+ " -oftpd_banner=erlang_otp_testing"
+ " -oanon_root=",PrivDir
+ ],
+ ?fmt("Cmnd=~s~n",[Cmnd]),
+ case os:cmd(Cmnd) of
+ [] ->
+ {ok,{"localhost",9999,"ftp","[email protected]"}};
+ Other ->
+ {error,Other}
+ end.
+
+cmnd_stop_server({ok,{_Host,Port,_Usr,_Pwd}}) ->
+ os:cmd("kill `netstat -tpln | grep "++integer_to_list(Port)++" | awk '{print $7}' | awk -F/ '{print $1}'`").
+
+cmnd_start_client({ok,{Host,Port,Usr,Pwd}}) ->
+ ?fmt('Call cmnd_start_client(~p)...',[{Host,Port,Usr,Pwd}]),
+ case inets:start(ftpc, [{host,Host},{port,Port}]) of
+ {ok,Client} ->
+ ?fmt("~p...",[{ok,Client}]),
+ case ftp:user(Client, Usr, Pwd) of
+ ok ->
+ ?fmt("OK!~n",[]),
+ {ok,Client};
+ Other ->
+ ?fmt("Other1=~p~n",[Other]),
+ inets:stop(ftpc,Client), Other
+ end;
+ Other ->
+ ?fmt("Other2=~p~n",[Other]),
+ Other
+ end.
+
+cmnd_stop_client({ok,Client}) ->
+ ?fmt('Call cmnd_stop_client(~p)~n',[Client]),
+ inets:stop(ftpc, Client). %% -> ok | Other
+
+cmnd_delete({ok,Client}, {Name,_ExpectedValue}) ->
+ ?fmt('Call cmnd_delete(~p, ~p)~n',[Client,Name]),
+ R=ftp:delete(Client, Name),
+ ?fmt("R=~p~n",[R]),
+ R.
+
+cmnd_put({ok,Client}, Name, Value) ->
+ ?fmt('Call cmnd_put(~p, ~p, ~p)...',[Client, Name, Value]),
+ R = ftp:send_bin(Client, unicode:characters_to_binary(Value), Name), % ok | {error,Error}
+ ?fmt('~p~n',[R]),
+ R.
+
+cmnd_get({ok,Client}, {Name,_ExpectedValue}) ->
+ ?fmt('Call cmnd_get(~p, ~p)~n',[Client,Name]),
+ case ftp:recv_bin(Client, Name) of
+ {ok,Bin} -> {ok, unicode:characters_to_list(Bin)};
+ Other -> Other
+ end.
+
+
+clear_files(Dir) ->
+ os:cmd(["rm -fr ",filename:join(Dir,"*")]).
diff --git a/lib/inets/test/property_test/ftp_simple_client_server_data/vsftpd.conf b/lib/inets/test/property_test/ftp_simple_client_server_data/vsftpd.conf
new file mode 100644
index 0000000000..fd48e2abf0
--- /dev/null
+++ b/lib/inets/test/property_test/ftp_simple_client_server_data/vsftpd.conf
@@ -0,0 +1,26 @@
+
+###
+### Some parameters are given in the vsftpd start command.
+###
+### Typical command-line paramters are such that has a file path
+### component like cert files.
+###
+
+
+listen=YES
+listen_port=9999
+run_as_launching_user=YES
+ssl_enable=NO
+#allow_anon_ssl=YES
+
+background=YES
+
+write_enable=YES
+anonymous_enable=YES
+anon_upload_enable=YES
+anon_mkdir_write_enable=YES
+anon_other_write_enable=YES
+anon_world_readable_only=NO
+
+### Shouldn't be necessary....
+require_ssl_reuse=NO
diff --git a/lib/inets/test/tftp_SUITE.erl b/lib/inets/test/tftp_SUITE.erl
index 59fb644667..09049e36af 100644
--- a/lib/inets/test/tftp_SUITE.erl
+++ b/lib/inets/test/tftp_SUITE.erl
@@ -1,18 +1,19 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2006-2011. All Rights Reserved.
+%% Copyright Ericsson AB 2006-2016. 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.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
+%%
+%% http://www.apache.org/licenses/LICENSE-2.0
+%%
+%% Unless required by applicable law or agreed to in writing, software
+%% distributed under the License is distributed on an "AS IS" BASIS,
+%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+%% See the License for the specific language governing permissions and
+%% limitations under the License.
%%
%% %CopyrightEnd%
%%
@@ -75,7 +76,7 @@ suite() -> [{ct_hooks,[ts_install_cth]}].
all() ->
[simple, extra, reuse_connection, resend_client,
- resend_server].
+ resend_server, large_file].
groups() ->
[].
@@ -901,6 +902,41 @@ reuse_connection(Config) when is_list(Config) ->
ok.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% Large file: transfer > 65535 blocks
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+large_file(doc) ->
+ ["Start the daemon and test transfer of files greater than 32M."];
+large_file(suite) ->
+ [];
+large_file(Config) when is_list(Config) ->
+ ?VERIFY(ok, application:start(inets)),
+
+ {Port, DaemonPid} = ?IGNORE(?START_DAEMON(0, [{debug, brief}])),
+
+ %% Read fail
+ RemoteFilename = "tftp_temporary_large_file_remote_test_file.txt",
+ LocalFilename = "tftp_temporary_large_file_local_test_file.txt",
+
+ {ok, FH} = file:open(LocalFilename, [write,exclusive]),
+ {ok, Size} = file:position(FH, {eof, 2*512*65535}),
+ ok = file:truncate(FH),
+ ?IGNORE(file:close(FH)),
+
+ %% Write and read
+ ?VERIFY({ok, Size}, tftp:write_file(RemoteFilename, LocalFilename, [{port, Port}])),
+ ?IGNORE(file:delete(LocalFilename)),
+ ?VERIFY({ok, Size}, tftp:read_file(RemoteFilename, LocalFilename, [{port, Port}])),
+
+ %% Cleanup
+ unlink(DaemonPid),
+ exit(DaemonPid, kill),
+ ?VERIFY(ok, file:delete(LocalFilename)),
+ ?VERIFY(ok, file:delete(RemoteFilename)),
+ ?VERIFY(ok, application:stop(inets)),
+ ok.
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% Goodies
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
diff --git a/lib/inets/test/tftp_test_lib.erl b/lib/inets/test/tftp_test_lib.erl
index e9b691828f..f07795324f 100644
--- a/lib/inets/test/tftp_test_lib.erl
+++ b/lib/inets/test/tftp_test_lib.erl
@@ -1,18 +1,19 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2007-2010. All Rights Reserved.
+%% Copyright Ericsson AB 2007-2016. 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.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
+%%
+%% http://www.apache.org/licenses/LICENSE-2.0
+%%
+%% Unless required by applicable law or agreed to in writing, software
+%% distributed under the License is distributed on an "AS IS" BASIS,
+%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+%% See the License for the specific language governing permissions and
+%% limitations under the License.
%%
%% %CopyrightEnd%
%%
diff --git a/lib/inets/test/tftp_test_lib.hrl b/lib/inets/test/tftp_test_lib.hrl
index bef024720a..e7a5a37d2c 100644
--- a/lib/inets/test/tftp_test_lib.hrl
+++ b/lib/inets/test/tftp_test_lib.hrl
@@ -1,18 +1,19 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2007-2011. All Rights Reserved.
+%% Copyright Ericsson AB 2007-2016. 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.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
+%%
+%% http://www.apache.org/licenses/LICENSE-2.0
+%%
+%% Unless required by applicable law or agreed to in writing, software
+%% distributed under the License is distributed on an "AS IS" BASIS,
+%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+%% See the License for the specific language governing permissions and
+%% limitations under the License.
%%
%% %CopyrightEnd%
%%
diff --git a/lib/inets/test/uri_SUITE.erl b/lib/inets/test/uri_SUITE.erl
index 9ba09e1474..b26c645821 100644
--- a/lib/inets/test/uri_SUITE.erl
+++ b/lib/inets/test/uri_SUITE.erl
@@ -1,18 +1,19 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2004-2013. All Rights Reserved.
+%% Copyright Ericsson AB 2004-2016. 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/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% 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.
+%% http://www.apache.org/licenses/LICENSE-2.0
+%%
+%% Unless required by applicable law or agreed to in writing, software
+%% distributed under the License is distributed on an "AS IS" BASIS,
+%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+%% See the License for the specific language governing permissions and
+%% limitations under the License.
%%
%% %CopyrightEnd%
%%
@@ -46,8 +47,10 @@ all() ->
userinfo,
scheme,
queries,
+ fragments,
escaped,
- hexed_query
+ hexed_query,
+ scheme_validation
].
%%--------------------------------------------------------------------
@@ -105,6 +108,42 @@ queries(Config) when is_list(Config) ->
{ok, {http,[],"localhost",8888,"/foobar.html","?foo=bar&foobar=42"}} =
http_uri:parse("http://localhost:8888/foobar.html?foo=bar&foobar=42").
+fragments(Config) when is_list(Config) ->
+ {ok, {http,[],"localhost",80,"/",""}} =
+ http_uri:parse("http://localhost#fragment"),
+ {ok, {http,[],"localhost",80,"/path",""}} =
+ http_uri:parse("http://localhost/path#fragment"),
+ {ok, {http,[],"localhost",80,"/","?query"}} =
+ http_uri:parse("http://localhost?query#fragment"),
+ {ok, {http,[],"localhost",80,"/path","?query"}} =
+ http_uri:parse("http://localhost/path?query#fragment"),
+ {ok, {http,[],"localhost",80,"/","","#fragment"}} =
+ http_uri:parse("http://localhost#fragment", [{fragment,true}]),
+ {ok, {http,[],"localhost",80,"/path","","#fragment"}} =
+ http_uri:parse("http://localhost/path#fragment", [{fragment,true}]),
+ {ok, {http,[],"localhost",80,"/","?query","#fragment"}} =
+ http_uri:parse("http://localhost?query#fragment", [{fragment,true}]),
+ {ok, {http,[],"localhost",80,"/path","?query","#fragment"}} =
+ http_uri:parse("http://localhost/path?query#fragment",
+ [{fragment,true}]),
+ {ok, {http,[],"localhost",80,"/","",""}} =
+ http_uri:parse("http://localhost", [{fragment,true}]),
+ {ok, {http,[],"localhost",80,"/path","",""}} =
+ http_uri:parse("http://localhost/path", [{fragment,true}]),
+ {ok, {http,[],"localhost",80,"/","?query",""}} =
+ http_uri:parse("http://localhost?query", [{fragment,true}]),
+ {ok, {http,[],"localhost",80,"/path","?query",""}} =
+ http_uri:parse("http://localhost/path?query", [{fragment,true}]),
+ {ok, {http,[],"localhost",80,"/","","#"}} =
+ http_uri:parse("http://localhost#", [{fragment,true}]),
+ {ok, {http,[],"localhost",80,"/path","","#"}} =
+ http_uri:parse("http://localhost/path#", [{fragment,true}]),
+ {ok, {http,[],"localhost",80,"/","?query","#"}} =
+ http_uri:parse("http://localhost?query#", [{fragment,true}]),
+ {ok, {http,[],"localhost",80,"/path","?query","#"}} =
+ http_uri:parse("http://localhost/path?query#", [{fragment,true}]),
+ ok.
+
escaped(Config) when is_list(Config) ->
{ok, {http,[],"www.somedomain.com",80,"/%2Eabc",[]}} =
http_uri:parse("http://www.somedomain.com/%2Eabc"),
@@ -137,6 +176,26 @@ hexed_query(Config) when is_list(Config) ->
verify_uri(URI2, Verify2),
verify_uri(URI3, Verify3).
+scheme_validation(Config) when is_list(Config) ->
+ {ok, {http,[],"localhost",80,"/",""}} =
+ http_uri:parse("http://localhost#fragment"),
+
+ ValidationFun =
+ fun("http") -> valid;
+ (_) -> {error, bad_scheme}
+ end,
+
+ {ok, {http,[],"localhost",80,"/",""}} =
+ http_uri:parse("http://localhost#fragment",
+ [{scheme_validation_fun, ValidationFun}]),
+ {error, bad_scheme} =
+ http_uri:parse("https://localhost#fragment",
+ [{scheme_validation_fun, ValidationFun}]),
+ %% non-fun scheme_validation_fun works as no option passed
+ {ok, {https,[],"localhost",443,"/",""}} =
+ http_uri:parse("https://localhost#fragment",
+ [{scheme_validation_fun, none}]).
+
%%--------------------------------------------------------------------
%% Internal Functions ------------------------------------------------