diff options
author | Tim Rühsen <tim.ruehsen@gmx.de> | 2015-08-28 15:43:22 +0200 |
---|---|---|
committer | Tim Rühsen <tim.ruehsen@gmx.de> | 2015-08-28 15:43:22 +0200 |
commit | 57cea296730bafb7d90eaa95fc03e12e44e9d0ab (patch) | |
tree | 5b3edf7b5462f782f9a90bfc57d590b904f49ab3 | |
parent | a9ba54e76ae6533ca7dbd9200ca597f533745d69 (diff) | |
download | wget-tim/wget2.tar.gz |
Merge test suite from Mget as tests2/tim/wget2
53 files changed, 9717 insertions, 118 deletions
diff --git a/Makefile.am b/Makefile.am index b5936437..c9b982b0 100644 --- a/Makefile.am +++ b/Makefile.am @@ -41,7 +41,7 @@ distuninstallcheck_listfiles = find . -type f | \ ACLOCAL_AMFLAGS = -I m4 # subdirectories in the distribution -SUBDIRS = lib src doc po include libwget src2 examples tests util testenv +SUBDIRS = lib src doc po include libwget src2 examples tests tests2 util testenv EXTRA_DIST = MAILING-LIST \ msdos/config.h msdos/Makefile.DJ \ diff --git a/include/libwget.h b/include/libwget.h index 36ff1738..0b3e48b8 100644 --- a/include/libwget.h +++ b/include/libwget.h @@ -1224,8 +1224,6 @@ void wget_ssl_set_config_string(int key, const char *value); void wget_ssl_set_config_int(int key, int value); -//void * -// wget_ssl_open(int sockfd, const char *hostname, int connect_timeout) G_GNUC_WGET_NONNULL((2)); int wget_ssl_open(wget_tcp_t *tcp); void @@ -1237,8 +1235,8 @@ void wget_ssl_server_init(void); void wget_ssl_server_deinit(void); -void * - wget_ssl_server_open(int sockfd, int connect_timeout); +int + wget_ssl_server_open(wget_tcp_t *tcp); void wget_ssl_server_close(void **session); @@ -1419,7 +1417,7 @@ const char * const char * wget_http_parse_connection(const char *s, char *keep_alive) G_GNUC_WGET_NONNULL_ALL; const char * - wget_http_parse_setcookie(const char *s, wget_cookie_t *cookie) G_GNUC_WGET_NONNULL_ALL; + wget_http_parse_setcookie(const char *s, wget_cookie_t *cookie) G_GNUC_WGET_NONNULL((1)); const char * wget_http_parse_etag(const char *s, const char **etag) G_GNUC_WGET_NONNULL((1)); diff --git a/libwget/cookie.c b/libwget/cookie.c index 632d6ec2..bbc295ac 100644 --- a/libwget/cookie.c +++ b/libwget/cookie.c @@ -57,20 +57,20 @@ struct wget_cookie_db_st { int wget_cookie_db_load_psl(wget_cookie_db_t *cookie_db, const char *fname) { #ifdef HAVE_LIBPSL - if (fname) { - psl_ctx_t *psl = psl_load_file(fname); + if (fname) { + psl_ctx_t *psl = psl_load_file(fname); - if (psl) - psl_free(cookie_db->psl); - cookie_db->psl = psl; - } else { + if (psl) psl_free(cookie_db->psl); - cookie_db->psl = NULL; - } + cookie_db->psl = psl; + } else { + psl_free(cookie_db->psl); + cookie_db->psl = psl_builtin(); + } - return 0; + return 0; #else - return -1; + return -1; #endif } diff --git a/libwget/css.c b/libwget/css.c index 1f2b1d95..75168180 100644 --- a/libwget/css.c +++ b/libwget/css.c @@ -157,9 +157,6 @@ void wget_css_parse_file( { int fd; - if (!fname) - return; - if (strcmp(fname,"-")) { if ((fd = open(fname, O_RDONLY)) != -1) { struct stat st; diff --git a/libwget/encoding.c b/libwget/encoding.c index 77cfab54..12e1d22b 100644 --- a/libwget/encoding.c +++ b/libwget/encoding.c @@ -106,7 +106,7 @@ char *wget_charset_transcode(const char *src, const char *src_encoding, const ch ret = strndup(dst, dst_len - dst_len_tmp); debug_printf("converted '%s' (%s) -> '%s' (%s)\n", src, src_encoding, ret, dst_encoding); } else - error_printf(_("Failed to convert '%s' string into '%s' (%d)\n"), src_encoding, dst_encoding, errno); + error_printf(_("Failed to convert '%s' string into '%s' (%d): '%s'\n"), src_encoding, dst_encoding, errno, src); xfree(dst); iconv_close(cd); @@ -127,6 +127,11 @@ int wget_str_needs_encoding(const char *s) return !!*s; } +char *wget_str_to_utf8(const char *src, const char *encoding) +{ + return wget_charset_transcode(src, encoding, "utf-8"); +} + int wget_str_is_valid_utf8(const char *utf8) { const unsigned char *s = (const unsigned char *) utf8; @@ -153,11 +158,6 @@ int wget_str_is_valid_utf8(const char *utf8) return 1; } -char *wget_str_to_utf8(const char *src, const char *encoding) -{ - return wget_charset_transcode(src, encoding, "utf-8"); -} - char *wget_utf8_to_str(const char *src, const char *encoding) { return wget_charset_transcode(src, "utf-8", encoding); @@ -210,13 +210,27 @@ const char *wget_str_to_ascii(const char *src) char *asc = NULL; int rc; - // idna_to_ascii_8z() automatically converts UTF-8 to lowercase +/* + * Work around a libidn <= 1.30 vulnerability. + * + * The function checks for a valid UTF-8 character sequence before + * passing it to idna_to_ascii_8z(). + * + * [1] http://lists.gnu.org/archive/html/help-libidn/2015-05/msg00002.html + * [2] https://lists.gnu.org/archive/html/bug-wget/2015-06/msg00002.html + * [3] http://curl.haxx.se/mail/lib-2015-06/0143.html + */ + if (wget_is_valid_utf8(src)) { + // idna_to_ascii_8z() automatically converts UTF-8 to lowercase - if ((rc = idna_to_ascii_8z(src, &asc, IDNA_USE_STD3_ASCII_RULES)) == IDNA_SUCCESS) { - // debug_printf("toASCII '%s' -> '%s'\n", src, asc); - src = asc; - } else - error_printf(_("toASCII failed (%d): %s\n"), rc, idna_strerror(rc)); + if ((rc = idna_to_ascii_8z(src, &asc, IDNA_USE_STD3_ASCII_RULES)) == IDNA_SUCCESS) { + // debug_printf("toASCII '%s' -> '%s'\n", src, asc); + src = asc; + } else + error_printf(_("toASCII failed (%d): %s\n"), rc, idna_strerror(rc)); + } + else + error_printf(_("Invalid UTF-8 sequence not converted: '%s'\n"), src); } #else if (wget_str_needs_encoding(src)) { diff --git a/libwget/http.c b/libwget/http.c index ba11eac1..3ad56547 100644 --- a/libwget/http.c +++ b/libwget/http.c @@ -1514,7 +1514,7 @@ int wget_http_open(wget_http_connection_t **_conn, const wget_iri_t *iri) void wget_http_close(wget_http_connection_t **conn) { - if (conn && *conn) { + if (*conn) { wget_tcp_deinit(&(*conn)->tcp); // if (!wget_tcp_get_dns_caching()) // freeaddrinfo((*conn)->addrinfo); diff --git a/libwget/iri.c b/libwget/iri.c index cc6e2560..d4799d62 100644 --- a/libwget/iri.c +++ b/libwget/iri.c @@ -698,10 +698,14 @@ char *wget_iri_get_path(const wget_iri_t *iri, wget_buffer_t *buf, const char *e if (iri->path) { if (wget_strcasecmp_ascii(encoding, "utf-8")) { - char *fname = wget_utf8_to_str(iri->path, encoding); - if (fname) { + char *fname; + + if ((fname = wget_utf8_to_str(iri->path, encoding))) { wget_buffer_strcat(buf, fname); xfree(fname); + } else { + // conversion failed, keep original string + wget_buffer_strcat(buf, iri->path); } } else { wget_buffer_strcat(buf, iri->path); @@ -725,38 +729,37 @@ char *wget_iri_get_query_as_filename(const wget_iri_t *iri, wget_buffer_t *buf, if (wget_strcasecmp_ascii(encoding, "utf-8")) { if ((query = wget_utf8_to_str(iri->query, encoding))) allocated = 1; - } else { + else + query = iri->query; + } else query = iri->query; - } - if (query) { - int slashes = 0; - const char *src = query; + int slashes = 0; + const char *src = query; - // count slashes in query string - while ((src = strchr(src, '/'))) { - slashes++; - src++; - } + // count slashes in query string + while ((src = strchr(src, '/'))) { + slashes++; + src++; + } - if (slashes) { - // escape slashes to use query as part of a filename - const char *begin; - - for (src = begin = query; *src; src++) { - if (*src == '/') { - if (begin != src) - wget_buffer_memcat(buf, begin, src - begin); - begin = src + 1; - wget_buffer_memcat(buf, "%2F", 3); - } - } + if (slashes) { + // escape slashes to use query as part of a filename + const char *begin; - if (begin != src) - wget_buffer_memcat(buf, begin, src - begin); - } else { - wget_buffer_strcat(buf, query); + for (src = begin = query; *src; src++) { + if (*src == '/') { + if (begin != src) + wget_buffer_memcat(buf, begin, src - begin); + begin = src + 1; + wget_buffer_memcat(buf, "%2F", 3); + } } + + if (begin != src) + wget_buffer_memcat(buf, begin, src - begin); + } else { + wget_buffer_strcat(buf, query); } if (allocated) @@ -769,15 +772,19 @@ char *wget_iri_get_query_as_filename(const wget_iri_t *iri, wget_buffer_t *buf, char *wget_iri_get_filename(const wget_iri_t *iri, wget_buffer_t *buf, const char *encoding) { if (iri->path) { - char *fname; + char *fname, *p; if (wget_strcasecmp_ascii(encoding, "utf-8")) { - if ((fname = strrchr(iri->path, '/'))) - fname = wget_utf8_to_str(fname + 1, encoding); - else - fname = wget_utf8_to_str(iri->path, encoding); + if ((p = strrchr(iri->path, '/'))) { + if (!(fname = wget_utf8_to_str(p + 1, encoding))) + wget_buffer_strcat(buf, p + 1); // conversion failed, keep original string + } else { + if (!(fname = wget_utf8_to_str(iri->path, encoding))) + wget_buffer_strcat(buf, iri->path); // conversion failed, keep original string + } if (fname) { + // conversion succeeded wget_buffer_strcat(buf, fname); xfree(fname); } diff --git a/libwget/net.c b/libwget/net.c index eb208e34..ce9a08fc 100644 --- a/libwget/net.c +++ b/libwget/net.c @@ -180,10 +180,11 @@ struct addrinfo *wget_tcp_resolve(wget_tcp_t *tcp, const char *host, const char if (!tcp) tcp = &_global_tcp; - if (!port) - port = "0"; +// if (!port) +// port = "0"; - if (tcp->caching) { + // if port is NULL, + if (tcp->caching && port) { if ((addrinfo = _wget_dns_cache_get(host, port))) return addrinfo; @@ -198,7 +199,7 @@ struct addrinfo *wget_tcp_resolve(wget_tcp_t *tcp, const char *host, const char addrinfo = NULL; #if defined(AI_NUMERICSERV) - ai_flags |= (isdigit(*port) ? AI_NUMERICSERV : 0); + ai_flags |= (port && isdigit(*port) ? AI_NUMERICSERV : 0); #endif #if defined(AI_ADDRCONFIG) ai_flags |= AI_ADDRCONFIG; @@ -249,7 +250,7 @@ struct addrinfo *wget_tcp_resolve(wget_tcp_t *tcp, const char *host, const char if (rc) { error_printf(_("Failed to resolve %s:%s (%s)\n"), host, port, gai_strerror(rc)); - if (tcp->caching) + if (tcp->caching && port) wget_thread_mutex_unlock(&mutex); return NULL; @@ -302,7 +303,7 @@ struct addrinfo *wget_tcp_resolve(wget_tcp_t *tcp, const char *host, const char } } - if (tcp->caching) { + if (tcp->caching && port) { // In case of a race condition the already exisiting addrinfo is returned. // The addrinfo argument given to _wget_dns_cache_add() will be freed in this case. addrinfo = _wget_dns_cache_add(host, port, addrinfo); @@ -609,7 +610,7 @@ int wget_tcp_connect(wget_tcp_t *tcp, const char *host, const char *port) break; /* stop here - the server cert couldn't be validated */ } - // do not free tcp->addrinfo when calling mget_tcp_close() + // do not free tcp->addrinfo when calling wget_tcp_close() struct addrinfo *ai_tmp = tcp->addrinfo; tcp->addrinfo = NULL; wget_tcp_close(tcp); @@ -735,29 +736,18 @@ wget_tcp_t *wget_tcp_accept(wget_tcp_t *parent_tcp) int wget_tcp_tls_start(wget_tcp_t *tcp) { - int ret; - - // TODO: unify wget_ssl_open and wget_ssl_server_open - if (tcp->passive) { - if ((tcp->ssl_session = wget_ssl_server_open(tcp->sockfd, tcp->connect_timeout))) { - return 0; - } - ret = WGET_E_UNKNOWN; - } else { + if (tcp->passive) + return wget_ssl_server_open(tcp); + else return wget_ssl_open(tcp); - } - - return ret; } -void mget_tcp_tls_stop(wget_tcp_t *tcp) +void wget_tcp_tls_stop(wget_tcp_t *tcp) { - if (tcp->ssl_session) { - if (tcp->passive) - wget_ssl_server_close(&tcp->ssl_session); - else - wget_ssl_close(&tcp->ssl_session); - } + if (tcp->passive) + wget_ssl_server_close(&tcp->ssl_session); + else + wget_ssl_close(&tcp->ssl_session); } ssize_t wget_tcp_read(wget_tcp_t *tcp, char *buf, size_t count) @@ -788,7 +778,7 @@ ssize_t wget_tcp_write(wget_tcp_t *tcp, const char *buf, size_t count) ssize_t nwritten = 0, n; int rc; - if (tcp->ssl) + if (tcp->ssl_session) return wget_ssl_write_timeout(tcp->ssl_session, buf, count, tcp->timeout); while (count) { @@ -885,12 +875,7 @@ ssize_t wget_tcp_printf(wget_tcp_t *tcp, const char *fmt, ...) void wget_tcp_close(wget_tcp_t *tcp) { if (tcp) { - if (tcp->ssl && tcp->ssl_session) { - if (tcp->passive) - wget_ssl_server_close(&tcp->ssl_session); - else - wget_ssl_close(&tcp->ssl_session); - } + wget_tcp_tls_stop(tcp); if (tcp->sockfd != -1) { close(tcp->sockfd); tcp->sockfd = -1; diff --git a/libwget/ssl_gnutls.c b/libwget/ssl_gnutls.c index ead5174b..15f32fd2 100644 --- a/libwget/ssl_gnutls.c +++ b/libwget/ssl_gnutls.c @@ -1278,13 +1278,21 @@ void wget_ssl_server_deinit(void) wget_thread_mutex_unlock(&_mutex); } -void *wget_ssl_server_open(int sockfd, int connect_timeout) +int wget_ssl_server_open(wget_tcp_t *tcp) { gnutls_session_t session; + int ret = WGET_E_UNKNOWN; + int rc, sockfd, connect_timeout; + + if (!tcp) + return WGET_E_INVALID; if (!_init) wget_ssl_server_init(); + sockfd= tcp->sockfd; + connect_timeout = tcp->connect_timeout; + #ifdef GNUTLS_NONBLOCK gnutls_init(&session, GNUTLS_SERVER | GNUTLS_NONBLOCK); #else @@ -1305,41 +1313,52 @@ void *wget_ssl_server_open(int sockfd, int connect_timeout) // Wait for socket being ready before we call gnutls_handshake(). // I had problems on a KVM Win7 + CygWin (gnutls 3.2.4-1). - int ret = wget_ready_2_write(sockfd, connect_timeout); + rc = wget_ready_2_write(sockfd, connect_timeout); // Perform the TLS handshake - while (ret > 0) { - ret = gnutls_handshake(session); - if (ret == 0 || gnutls_error_is_fatal(ret)) { - if (ret == 0) - ret = 1; + while (rc > 0) { + rc = gnutls_handshake(session); + if (rc == 0 || gnutls_error_is_fatal(rc)) { + if (rc == 0) { + ret = WGET_E_SUCCESS; + } else { + error_printf("GnuTLS: (%d) %s\n", rc, gnutls_strerror(rc)); + + if (rc == GNUTLS_E_CERTIFICATE_ERROR) + ret = WGET_E_CERTIFICATE; + else + ret = WGET_E_HANDSHAKE; + } break; } if (gnutls_record_get_direction(session)) { // wait for writeability - ret = wget_ready_2_write(sockfd, connect_timeout); + rc = wget_ready_2_write(sockfd, connect_timeout); } else { // wait for readability - ret = wget_ready_2_read(sockfd, connect_timeout); + rc = wget_ready_2_read(sockfd, connect_timeout); } } - if (ret <= 0) { - if (ret) - debug_printf("Server handshake failed (%d)\n", ret); - else - debug_printf("Server handshake timed out\n"); + if (_config.print_info) + _print_info(session); - error_printf("GnuTLS Server: %s\n", gnutls_strerror(ret)); + if (ret == WGET_E_UNKNOWN) { + if (rc == 0) { + debug_printf("Server handshake timed out\n"); + ret = WGET_E_TIMEOUT; + } + } + if (ret == WGET_E_SUCCESS) { + debug_printf("Server handshake completed\n"); + tcp->ssl_session = session; + } else { gnutls_deinit(session); - return NULL; } - debug_printf("Server handshake completed\n"); - - return session; + return ret; } void wget_ssl_server_close(void **session) @@ -1399,7 +1418,7 @@ ssize_t wget_ssl_read_timeout(void *session, char *buf, size_t count, int timeou ssize_t wget_ssl_write_timeout(void *session, const char *buf, size_t count, int timeout) { return 0; } void wget_ssl_server_init(void) { } void wget_ssl_server_deinit(void) { } -void *wget_ssl_server_open(int sockfd, int connect_timeout) { return NULL; } +int wget_ssl_server_open(wget_tcp_t *tcp) { return WGET_E_UNKNOWN; } void wget_ssl_server_close(void **session) { } #endif // !HAVE_LIBGNUTLS diff --git a/tests2/Makefile.am b/tests2/Makefile.am new file mode 100644 index 00000000..31a67073 --- /dev/null +++ b/tests2/Makefile.am @@ -0,0 +1,33 @@ +#DEFS = @DEFS@ -DDATADIR=\"$(datadir)/@PACKAGE@\" -DSRCDIR=\"$(srcdir)\" +DEFS = @DEFS@ -DDATADIR=\"$(top_srcdir)/data\" -DSRCDIR=\"$(srcdir)\" +AM_CPPFLAGS = -Wno-missing-field-initializers -I$(top_srcdir)/include +AM_LDFLAGS = -static +LDADD = libtest.la ../libwget/libwget-@LIBWGET_API_VERSION@.la @LTLIBICONV@ @LTLIBINTL@ $(LIBIDN2) $(LIBUNISTRING) $(LIBPTHREAD) + +# test-iri-disabled removed since Mget always uses IRIs +WGET_TESTS = test test-wget-1 test-restrict-ascii test-i-http test-i-https test-np test--spider-r \ + test-meta-robots test-idn-robots test-idn-meta test-idn-cmd \ + test-iri test-iri-percent test-iri-list test-iri-forced-remote \ + test-auth-basic test-parse-html test-parse-rss test--page-requisites test--accept \ + test-k test--follow-tags test-directory-clash test-ftp test-ftps + +#test--post-file test-E-k + +check_PROGRAMS = buffer_printf2_perf stringmap_perf $(WGET_TESTS) + +test_SOURCES = test.c +test_LDADD = ../libwget/libwget-@LIBWGET_API_VERSION@.la ../src2/wget2-log.o ../src2/wget2-options.o @LTLIBICONV@ @LTLIBINTL@ $(LIBIDN2) $(LIBUNISTRING) $(LIBPTHREAD) +test_parse_html_LDADD = ../libwget/libwget-@LIBWGET_API_VERSION@.la ../src2/wget2-log.o ../src2/wget2-options.o @LTLIBICONV@ @LTLIBINTL@ $(LIBIDN2) $(LIBUNISTRING) $(LIBPTHREAD) + +noinst_LTLIBRARIES = libtest.la +libtest_la_SOURCES = libtest.c +libtest_la_CPPFLAGS = -I$(srcdir) -I$(top_srcdir)/include +#libtest_LDADD = libtest.o + +EXTRA_DIST = files libtest.h certs + +clean-local: + rm -rf $(srcdir)/.test_* + +AM_TESTS_ENVIRONMENT = export VALGRIND_TESTS"=@VALGRIND_TESTS@"; +TESTS = $(WGET_TESTS) diff --git a/tests2/buffer_printf2_perf.c b/tests2/buffer_printf2_perf.c new file mode 100644 index 00000000..d7edf576 --- /dev/null +++ b/tests2/buffer_printf2_perf.c @@ -0,0 +1,81 @@ +/* + * Copyright(c) 2012 Tim Ruehsen + * + * This file is part of MGet. + * + * Wget is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Wget is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Wget. If not, see <http://www.gnu.org/licenses/>. + * + * + * testing performance of buffer printf routines + * + * Changelog + * 06.07.2012 Tim Ruehsen created + * + */ + +#if HAVE_CONFIG_H +# include <config.h> +#endif + +#include <stdio.h> + +#include <libwget.h> + +int main(void) +{ + int it; + wget_buffer_t buf; + char sbuf[128]; + + wget_buffer_init(&buf, sbuf, sizeof(sbuf)); + + for (it = 0; it < 10000000; it++) { + // buffer: 0.239s libc: 0.018s (gcc replaces sprintf(%s) by strcpy()) +// snprintf(sbuf,sizeof(sbuf),"%s", "teststring sabbeldi heidewitzka\n"); +// buffer_printf2(&buf,"%s", "teststring sabbeldi heidewitzka\n"); + + // buffer: 0.306s libc: 1.040s +// sprintf(sbuf,"%s\n", "teststring sabbeldi heidewitzka\n"); +// buffer_printf2(&buf,"%s\n", "teststring sabbeldi heidewitzka\n"); + + // function call and loop overhead: buffer: 0.072s libc: 0.390s +// buffer_printf2(&buf, "", "teststring sabbeldi heidewitzka\n"); +// sprintf(sbuf, "", "teststring sabbeldi heidewitzka\n"); + + // buffer: 0.392s libc: 0.838s +// sprintf(sbuf,"%.*s\n", 17, "teststring sabbeldi heidewitzka\n"); +// buffer_printf2(&buf,"%.*s\n", 17, "teststring sabbeldi heidewitzka\n"); + + // buffer: 0.407s libc: 0.960s +// sprintf(sbuf,"%d\n", it); +// buffer_printf2(&buf,"%d\n", it); + + // buffer: 0.643s libc/sprintf: 1.251s libc/snprintf: 1.253s +// snprintf(sbuf,sizeof(sbuf),"%10.*d\n", 8, it); +// sprintf(sbuf,"%10.*d\n", 8, it); +// buffer_printf2(&buf,"%10.*d\n", 8, it); + + // buffer: 0.456s libc: 0.867s +// sprintf(sbuf,"%X\n", it); + wget_buffer_printf2(&buf, "%X\n", it); + + // buffer: 0.955s libc: 1.648s +// sprintf(sbuf,"teststring %s sabbeldi %d\n", "[foobar foobar foobar]", it); +// buffer_printf2(&buf,"teststring %s sabbeldi %d\n", "[foobar foobar foobar]", it); + } + + wget_buffer_deinit(&buf); + + return 0; +} diff --git a/tests2/certs/README b/tests2/certs/README new file mode 100644 index 00000000..ae9de6e8 --- /dev/null +++ b/tests2/certs/README @@ -0,0 +1,77 @@ +To create the server RSA private key: +$ certtool --generate-privkey --outfile x509-server-key.pem --rsa + + +To create a self signed CA certificate: +$ certtool --generate-privkey --outfile x509-ca-key.pem +$ certtool --generate-self-signed --load-privkey x509-ca-key.pem --outfile x509-ca-cert.pem +Common name: Mget +UID: +Organizational unit name: Mget +Organization name: rockdaboot +Locality name: +State or province name: +Country name (2 chars): +Enter the subject's domain component (DC): +This field should not be used in new certificates. +E-mail: +Enter the certificate's serial number in decimal (default: 6080487640893163573): + +Activation/Expiration time. +The certificate will expire in (days): -1 + +Extensions. +Does the certificate belong to an authority? (y/N): y +Path length constraint (decimal, -1 for no constraint): +Is this a TLS web client certificate? (y/N): +Will the certificate be used for IPsec IKE operations? (y/N): +Is this a TLS web server certificate? (y/N): +Enter a dnsName of the subject of the certificate: +Enter a URI of the subject of the certificate: +Enter the IP address of the subject of the certificate: +Enter the e-mail of the subject of the certificate: +Will the certificate be used to sign other certificates? (y/N): y +Will the certificate be used to sign CRLs? (y/N): y +Will the certificate be used to sign code? (y/N): +Will the certificate be used to sign OCSP requests? (y/N): y +Will the certificate be used for time stamping? (y/N): +Enter the URI of the CRL distribution point: + + +To generate a server certificate using the private key only: +$ certtool --generate-certificate --load-privkey x509-server-key.pem --outfile x509-server-cert.pem --load-ca-certificate x509-ca-cert.pem --load-ca-privkey x509-ca-key.pem +Common name: 127.0.0.1 +UID: +Organizational unit name: Mget +Organization name: rockdaboot +Locality name: +State or province name: +Country name (2 chars): +Enter the subject's domain component (DC): +This field should not be used in new certificates. +E-mail: +Enter the certificate's serial number in decimal (default: 6080488276853553635): + +Activation/Expiration time. +The certificate will expire in (days): -1 + +Extensions. +Does the certificate belong to an authority? (y/N): +Is this a TLS web client certificate? (y/N): +Will the certificate be used for IPsec IKE operations? (y/N): +Is this a TLS web server certificate? (y/N): y +Enter a dnsName of the subject of the certificate: 127.0.0.1 +Enter a dnsName of the subject of the certificate: localhost +Enter a dnsName of the subject of the certificate: +Enter a URI of the subject of the certificate: +Enter the IP address of the subject of the certificate: +Will the certificate be used for signing (DHE and RSA-EXPORT ciphersuites)? (Y/n): +Will the certificate be used for encryption (RSA ciphersuites)? (Y/n): + + +To create a CRL for the server certificate: +$ certtool --generate-crl --load-ca-privkey x509-ca-key.pem --load-ca-certificate x509-ca-cert.pem --load-certificate x509-server-cert.pem --outfile x509-server-crl.pem +Generating a signed CRL... +Update times. +The certificate will expire in (days): -1 +CRL Number (default: 6080006793650397145): diff --git a/tests2/certs/x509-ca-cert.pem b/tests2/certs/x509-ca-cert.pem new file mode 100644 index 00000000..95fd8f82 --- /dev/null +++ b/tests2/certs/x509-ca-cert.pem @@ -0,0 +1,22 @@ +-----BEGIN CERTIFICATE----- +MIIDpDCCAlygAwIBAgIIVOoKhxVSl5wwDQYJKoZIhvcNAQELBQAwMzENMAsGA1UE +AxMETWdldDENMAsGA1UECxMETWdldDETMBEGA1UEChMKcm9ja2RhYm9vdDAiGA8y +MDE1MDIyMjE2NTc0NloYDzk5OTkxMjMxMjM1OTU5WjAzMQ0wCwYDVQQDEwRNZ2V0 +MQ0wCwYDVQQLEwRNZ2V0MRMwEQYDVQQKEwpyb2NrZGFib290MIIBUjANBgkqhkiG +9w0BAQEFAAOCAT8AMIIBOgKCATEAwrMa15OMLS3aW2g/U2ASSHYZ5+lGema1vBjg +d7TVN6hi+m3UU3S5P+7U9K83uWEQjK8Fuf+uS3bN4ltmAEkOoWm9JrGIh809CprJ +fz0csR1i+z6vylNadMxTFFBpPgnzBxOuD6SpXcxHCJ5blsyToPkdDzZFq3bdnn9n +IzfOn9hGDt7//nbEV+ypjKeTwAtOjnxlqyRnk74/KryoLtuEZ1UZEFZ4wpFDf95S +Ejb8TuarWy87/iPlHHXAgWfnUYByrIK0tCu028/3o51PXU++jikuBP/GF94S4YQF +m0FWwrbQfCmPgwS+Eg/S+xFzlfvbKmY/aRlEyww49n7HSJFBAxO0tKbZvx2ic6AX ++trMzcwUP1gkcfRc4TqxnMFN3W0Bm+aidLzPTHOQOhhcrI4QkwIDAQABo1gwVjAP +BgNVHRMBAf8EBTADAQH/MBMGA1UdJQQMMAoGCCsGAQUFBwMJMA8GA1UdDwEB/wQF +AwMHBgAwHQYDVR0OBBYEFHEGnMpPofvpa59JwTdIcZ1ARc3DMA0GCSqGSIb3DQEB +CwUAA4IBMQCtrLovjm5ZdFbdbjbb2OOqEImSk+9moWsH78fNXjgiAXYOpsAiYYUj +/s3ho1NWOdXroj7G5gD7kFfFgEKD94eD3YbyEmnJPo0w1cD7Y6FmdKk9I0SdsHtZ +CEboHYnjV5Prgm0XxREzXuZzvrT57u+l319z6Aiomdg3yntxLcGF/PqHcGsdpRC0 +kHPJjxEADYDkRK7U4Osmpl7G6KOmLRh7ZdPZd+WXNQ/tfcgTrFdxuf3ufQe0sNR2 ++o6oXhfuOJn8Xhv4JmVtkKZb+tr2/4UGEUiryICLHZkeIDPYANUOtxtZ5Yw+nHfH +3Lr2jJlwUkPw2HXJt88nkGPm3ZLwEvIfe53OHqJw2IDlLoZ0LY+CykeuShxek0+X +JiC0QAsEq2yoDsMr3gTa1ICC459s6RQO +-----END CERTIFICATE----- diff --git a/tests2/certs/x509-ca-key.pem b/tests2/certs/x509-ca-key.pem new file mode 100644 index 00000000..d46c979b --- /dev/null +++ b/tests2/certs/x509-ca-key.pem @@ -0,0 +1,165 @@ +Public Key Info: + Public Key Algorithm: RSA + Key Security Level: Normal (2432 bits) + +modulus: + 00:c2:b3:1a:d7:93:8c:2d:2d:da:5b:68:3f:53:60: + 12:48:76:19:e7:e9:46:7a:66:b5:bc:18:e0:77:b4: + d5:37:a8:62:fa:6d:d4:53:74:b9:3f:ee:d4:f4:af: + 37:b9:61:10:8c:af:05:b9:ff:ae:4b:76:cd:e2:5b: + 66:00:49:0e:a1:69:bd:26:b1:88:87:cd:3d:0a:9a: + c9:7f:3d:1c:b1:1d:62:fb:3e:af:ca:53:5a:74:cc: + 53:14:50:69:3e:09:f3:07:13:ae:0f:a4:a9:5d:cc: + 47:08:9e:5b:96:cc:93:a0:f9:1d:0f:36:45:ab:76: + dd:9e:7f:67:23:37:ce:9f:d8:46:0e:de:ff:fe:76: + c4:57:ec:a9:8c:a7:93:c0:0b:4e:8e:7c:65:ab:24: + 67:93:be:3f:2a:bc:a8:2e:db:84:67:55:19:10:56: + 78:c2:91:43:7f:de:52:12:36:fc:4e:e6:ab:5b:2f: + 3b:fe:23:e5:1c:75:c0:81:67:e7:51:80:72:ac:82: + b4:b4:2b:b4:db:cf:f7:a3:9d:4f:5d:4f:be:8e:29: + 2e:04:ff:c6:17:de:12:e1:84:05:9b:41:56:c2:b6: + d0:7c:29:8f:83:04:be:12:0f:d2:fb:11:73:95:fb: + db:2a:66:3f:69:19:44:cb:0c:38:f6:7e:c7:48:91: + 41:03:13:b4:b4:a6:d9:bf:1d:a2:73:a0:17:fa:da: + cc:cd:cc:14:3f:58:24:71:f4:5c:e1:3a:b1:9c:c1: + 4d:dd:6d:01:9b:e6:a2:74:bc:cf:4c:73:90:3a:18: + 5c:ac:8e:10:93: + +public exponent: + 01:00:01: + +private exponent: + 3b:da:79:8e:fa:21:e6:a5:a8:f1:de:bb:50:f3:40: + cb:9b:da:dc:eb:5e:aa:34:36:fc:2b:1d:9e:4f:2e: + 18:dd:20:08:62:89:1a:5a:d0:b4:31:c4:af:af:c9: + ce:a8:63:41:0c:71:13:3b:e1:a5:fb:50:d1:9c:4d: + 60:1b:15:6f:53:a5:3d:66:e8:54:ef:28:2b:c1:67: + de:40:b8:38:4e:93:66:2f:60:35:2f:a8:a8:2d:44: + 01:03:b3:46:ca:22:36:f3:ba:d7:be:43:fe:bc:d4: + bd:76:89:2b:73:9a:92:aa:e2:5f:11:cd:1b:28:00: + 7b:40:29:41:af:5f:4a:ce:5e:c3:25:94:c6:f2:55: + eb:bd:aa:65:be:02:72:d0:47:07:10:80:e4:ba:dd: + 48:92:73:6e:a3:fa:ab:35:a7:55:bc:b7:37:c2:0d: + f0:37:ab:8f:27:24:67:27:ab:d9:66:9c:6f:c8:f6: + 30:d7:72:db:e6:b1:3a:a1:df:a2:2f:42:fd:1c:fd: + c8:14:0e:cc:23:e8:f6:ba:38:42:97:78:80:6f:7c: + c9:a0:99:1f:c6:83:95:a8:1e:3a:a2:f5:27:fb:6a: + 82:f2:23:fe:00:18:75:b2:24:2e:1e:50:ad:07:c5: + b3:92:88:19:41:6a:a1:a8:09:6a:53:ab:f1:8f:3d: + c8:c9:f3:d5:4d:de:0c:c3:21:6d:25:fb:a8:de:57: + 04:a2:9d:0f:d7:b5:8e:ca:2e:9a:4a:5a:c3:c3:95: + 28:b7:30:b0:05:7b:ca:d8:b0:04:d2:85:7b:15:fb: + 61:66:4d:01: + +prime1: + 00:df:3d:5b:db:0f:a9:c4:c8:b5:3e:8c:65:8f:e8: + d6:40:1c:d0:83:e5:2a:99:0e:3a:67:07:f0:37:86: + 51:c7:07:a7:68:51:ba:32:bd:3a:a9:89:a5:1d:fe: + 65:e7:45:10:e8:27:81:58:cc:a4:4b:38:af:60:26: + 58:9e:ed:78:f3:ed:7b:8a:08:9d:9c:7c:6c:b7:74: + be:36:36:02:73:ba:5e:d5:15:f6:73:e7:89:33:c5: + 7e:63:d1:6d:26:5c:87:7d:b7:0a:c8:56:83:c5:45: + 9d:69:b6:01:fd:5e:7c:ee:8d:bc:6a:23:77:ed:43: + 07:47:a3:46:fe:55:75:e8:de:f9:e9:d9:20:b5:35: + 6c:1f:72:03:38:2a:11:8f:e4:a9:ad:09:e9:75:9f: + 9e:ae:13: + +prime2: + 00:df:45:8e:87:45:6f:e6:fe:10:27:b6:f7:a2:9e: + 1d:b8:92:9b:18:84:bf:9a:04:66:4e:6f:42:58:cd: + e6:60:29:f4:9d:78:a3:79:23:0e:dd:93:8c:4b:0d: + d4:dc:ab:48:af:36:21:b1:a8:da:94:00:f6:dc:19: + 84:8b:19:2b:60:a4:ec:f2:ed:d8:5f:ad:5e:f1:6a: + fa:e2:29:71:29:93:29:d2:0a:88:67:be:80:d9:be: + fe:19:38:e3:20:90:c4:5a:3d:b2:d0:5c:33:89:07: + e3:55:48:a6:ac:63:a9:8e:8c:bc:0f:f3:71:42:2f: + 0b:60:27:28:0a:84:d8:0a:de:4b:3c:b6:da:4f:89: + e5:a5:e7:fd:5d:4d:24:00:11:b8:4c:33:5a:9e:bb: + 7d:63:81: + +coefficient: + 35:cc:a8:18:c0:03:10:e4:6d:f5:fb:93:20:ec:c9: + e6:f6:2e:a1:0f:a0:a7:d1:d3:ff:db:ab:ee:20:91: + 27:9a:39:eb:ac:7a:a8:98:7a:fb:1a:71:69:59:0f: + 8d:4c:52:e7:38:71:55:c0:de:83:b8:9f:c5:eb:66: + c3:27:35:6c:ab:63:62:9c:eb:e5:49:7d:01:82:60: + 87:7e:58:c7:39:39:69:e0:6d:a0:56:98:13:b1:79: + 9e:64:6d:5f:6f:91:70:8a:cd:d8:49:73:ce:83:01: + ba:61:fb:85:4c:d7:54:1e:3e:b0:87:38:0f:4e:d3: + f9:63:2b:e0:1f:bb:ea:a6:b2:4e:b4:e1:38:a1:f2: + c8:7d:23:49:8f:86:0a:f8:df:bd:93:92:87:ce:a6: + 1d:b8: + +exp1: + 5e:95:49:b0:d3:bf:13:30:12:92:90:bb:8b:30:94: + 6e:0f:87:4d:0a:b0:74:ae:b1:91:eb:ac:1c:6a:5d: + 85:9d:39:91:9a:66:f0:8e:7a:27:50:b9:53:ae:f0: + 8f:ff:14:3d:b8:57:36:3f:66:30:b4:b0:a1:65:3d: + d1:00:3e:69:e3:29:9f:7f:2d:00:1b:3b:98:b2:ee: + d0:5b:2b:c8:ca:a2:d9:57:77:d6:fd:b7:84:e6:dd: + 38:ff:87:66:64:77:c7:8c:e1:15:a6:8a:27:ef:e9: + d4:db:17:96:b9:0c:e7:a9:c7:b5:94:97:80:40:10: + fa:8a:34:4f:17:f8:60:14:f0:ff:e2:4d:d8:58:ed: + 19:99:9d:c1:93:19:63:c4:f7:1a:e8:83:30:a1:d3: + 82:5f: + +exp2: + 00:a2:70:97:c6:e1:05:0e:39:30:05:c4:ff:9c:07: + 8f:b6:16:ab:d2:85:da:64:b2:e8:c0:0e:00:66:5d: + bf:4b:9d:9a:c3:ea:de:7c:a6:be:0d:05:69:5f:bd: + bb:6d:a5:0c:a7:b5:29:84:79:46:35:c2:11:d8:86: + 94:41:23:59:c4:e1:99:27:11:56:88:1d:b9:e2:c9: + 23:a8:e1:df:dc:10:9e:af:9b:4c:2c:b6:94:46:57: + c7:c5:0f:f7:67:5d:0c:0e:5f:af:36:1a:ae:bf:f6: + c6:35:e9:3a:a2:57:8c:28:13:4a:4c:0c:a1:0d:36: + ee:fe:d0:de:37:f0:f8:c1:c7:83:53:b3:f1:57:47: + 0b:96:ce:17:2f:07:8d:b6:a3:2d:c3:fa:e4:e6:71: + a0:43:81: + + +Public Key ID: 71:06:9C:CA:4F:A1:FB:E9:6B:9F:49:C1:37:48:71:9D:40:45:CD:C3 +Public key's random art: ++--[ RSA 2432]----+ +| .....+=++ | +| +. o oEo| +| . o..+ .| +| + .* . | +| +S + o | +| . . o . | +| . .. | +| +. o | +| ooo+ | ++-----------------+ + +-----BEGIN RSA PRIVATE KEY----- +MIIFewIBAAKCATEAwrMa15OMLS3aW2g/U2ASSHYZ5+lGema1vBjgd7TVN6hi+m3U +U3S5P+7U9K83uWEQjK8Fuf+uS3bN4ltmAEkOoWm9JrGIh809CprJfz0csR1i+z6v +ylNadMxTFFBpPgnzBxOuD6SpXcxHCJ5blsyToPkdDzZFq3bdnn9nIzfOn9hGDt7/ +/nbEV+ypjKeTwAtOjnxlqyRnk74/KryoLtuEZ1UZEFZ4wpFDf95SEjb8TuarWy87 +/iPlHHXAgWfnUYByrIK0tCu028/3o51PXU++jikuBP/GF94S4YQFm0FWwrbQfCmP +gwS+Eg/S+xFzlfvbKmY/aRlEyww49n7HSJFBAxO0tKbZvx2ic6AX+trMzcwUP1gk +cfRc4TqxnMFN3W0Bm+aidLzPTHOQOhhcrI4QkwIDAQABAoIBMDvaeY76IealqPHe +u1DzQMub2tzrXqo0NvwrHZ5PLhjdIAhiiRpa0LQxxK+vyc6oY0EMcRM74aX7UNGc +TWAbFW9TpT1m6FTvKCvBZ95AuDhOk2YvYDUvqKgtRAEDs0bKIjbzute+Q/681L12 +iStzmpKq4l8RzRsoAHtAKUGvX0rOXsMllMbyVeu9qmW+AnLQRwcQgOS63UiSc26j ++qs1p1W8tzfCDfA3q48nJGcnq9lmnG/I9jDXctvmsTqh36IvQv0c/cgUDswj6Pa6 +OEKXeIBvfMmgmR/Gg5WoHjqi9Sf7aoLyI/4AGHWyJC4eUK0HxbOSiBlBaqGoCWpT +q/GPPcjJ89VN3gzDIW0l+6jeVwSinQ/XtY7KLppKWsPDlSi3MLAFe8rYsATShXsV ++2FmTQECgZkA3z1b2w+pxMi1Poxlj+jWQBzQg+UqmQ46ZwfwN4ZRxwenaFG6Mr06 +qYmlHf5l50UQ6CeBWMykSzivYCZYnu148+17igidnHxst3S+NjYCc7pe1RX2c+eJ +M8V+Y9FtJlyHfbcKyFaDxUWdabYB/V587o28aiN37UMHR6NG/lV16N756dkgtTVs +H3IDOCoRj+SprQnpdZ+erhMCgZkA30WOh0Vv5v4QJ7b3op4duJKbGIS/mgRmTm9C +WM3mYCn0nXijeSMO3ZOMSw3U3KtIrzYhsajalAD23BmEixkrYKTs8u3YX61e8Wr6 +4ilxKZMp0gqIZ76A2b7+GTjjIJDEWj2y0FwziQfjVUimrGOpjoy8D/NxQi8LYCco +CoTYCt5LPLbaT4nlpef9XU0kABG4TDNanrt9Y4ECgZhelUmw078TMBKSkLuLMJRu +D4dNCrB0rrGR66wcal2FnTmRmmbwjnonULlTrvCP/xQ9uFc2P2YwtLChZT3RAD5p +4ymffy0AGzuYsu7QWyvIyqLZV3fW/beE5t04/4dmZHfHjOEVpoon7+nU2xeWuQzn +qce1lJeAQBD6ijRPF/hgFPD/4k3YWO0ZmZ3BkxljxPca6IMwodOCXwKBmQCicJfG +4QUOOTAFxP+cB4+2FqvShdpksujADgBmXb9LnZrD6t58pr4NBWlfvbttpQyntSmE +eUY1whHYhpRBI1nE4ZknEVaIHbniySOo4d/cEJ6vm0wstpRGV8fFD/dnXQwOX682 +Gq6/9sY16TqiV4woE0pMDKENNu7+0N438PjBx4NTs/FXRwuWzhcvB422oy3D+uTm +caBDgQKBmDXMqBjAAxDkbfX7kyDsyeb2LqEPoKfR0//bq+4gkSeaOeuseqiYevsa +cWlZD41MUuc4cVXA3oO4n8XrZsMnNWyrY2Kc6+VJfQGCYId+WMc5OWngbaBWmBOx +eZ5kbV9vkXCKzdhJc86DAbph+4VM11QePrCHOA9O0/ljK+Afu+qmsk604Tih8sh9 +I0mPhgr4372TkofOph24 +-----END RSA PRIVATE KEY----- diff --git a/tests2/certs/x509-client-cert.pem b/tests2/certs/x509-client-cert.pem new file mode 100644 index 00000000..930e4ff9 --- /dev/null +++ b/tests2/certs/x509-client-cert.pem @@ -0,0 +1,21 @@ +-----BEGIN CERTIFICATE----- +MIIDijCCAkKgAwIBAgIEUvoTYjANBgkqhkiG9w0BAQsFADAXMRUwEwYDVQQDEwxN +Z2V0IHRlc3QgQ0EwIhgPMjAxNDAyMTExMjExMTRaGA8yMDE1MDIxMTEyMTExNFow +GzEZMBcGA1UEAxMQTWdldCB0ZXN0IGNsaWVudDCCAVIwDQYJKoZIhvcNAQEBBQAD +ggE/ADCCAToCggExAMnbJAFsp0B4xYqoHvCJCM76R2VAdYsqlSxA1pNSNw9GWpJG +fuKftjJJRr2n9x3AY56Z3sS+1DiFMfDljvwrtFzDp/bQNMqSsVL1Oic6maN0ZvIm +zFRQ9iPLRDnpp6u1yTjU1q5Tyvyc9Kk4WDrovYg0uk17XPnmnLNNLTicoveF2jyR +ZK6D/gfX8NRcc1/MDEgXJvn5ME/zbGd7zJyJTuz9/EVF5D8dMTI6nvEheRoBH3JN +VoDnoMgxn2t/IqDRZIBgSchNBUMn7c4IcWNJfIRE0aknRLxjUFNMUUEAnoZ44Gez +v/kca74AtBFzEaXEj5bCQNlYXQ5ortVoCKCYAgXsxIhX3UiQmcynGSTMx+sVR0Of +BzSspZNAh9mkWcDfnBRVN/AiL6GTZfmNBUZuMOcCAwEAAaN2MHQwDAYDVR0TAQH/ +BAIwADATBgNVHSUEDDAKBggrBgEFBQcDAjAPBgNVHQ8BAf8EBQMDB6AAMB0GA1Ud +DgQWBBRB0d9XNqMFDCjvq3o40vRsUFCneTAfBgNVHSMEGDAWgBRxBpzKT6H76Wuf +ScE3SHGdQEXNwzANBgkqhkiG9w0BAQsFAAOCATEAekKrNi/Phbrd4HDEgEdO/Jw7 +HDF5Wq4M1M1P0ZYsdkXjs1I0Gu8zLmrftt675ngfE9l9ZUvWpRSbi4r+3RGEwiTG +PqD82PSs2AyFG1RAzWyuzQb9JfdxhaVj6VEv26r3MujRgWK7eKsDqatMtQqoDyoq +KpYpKdRmVI6TMbifS769tvONzsoeIZJWXORqwtYW1MeVkkm5IcwWwjbtlSXnDPFD +ZSFm9nlwachTMUdq+ATr0KBBcD/EYt9QaH0FPRC2Bns/vYnOr+um5fYhLmNyNl/5 +iSU5tMv0GI/He0PpDx7GDBx3WqWatjxMUqx7jG0BJPsxrF5tjyN14Lk0264YcSb2 +mMWAtnRWtX0EpnRUVQYmHfMwgiGmRGi4+E7+G6IHT+qlW5D1zOfIF2jvMrWMLQ== +-----END CERTIFICATE----- diff --git a/tests2/certs/x509-client-key.pem b/tests2/certs/x509-client-key.pem new file mode 100644 index 00000000..1125fe11 --- /dev/null +++ b/tests2/certs/x509-client-key.pem @@ -0,0 +1,165 @@ +Public Key Info: + Public Key Algorithm: RSA + Key Security Level: Normal (2432 bits) + +modulus: + 00:c9:db:24:01:6c:a7:40:78:c5:8a:a8:1e:f0:89: + 08:ce:fa:47:65:40:75:8b:2a:95:2c:40:d6:93:52: + 37:0f:46:5a:92:46:7e:e2:9f:b6:32:49:46:bd:a7: + f7:1d:c0:63:9e:99:de:c4:be:d4:38:85:31:f0:e5: + 8e:fc:2b:b4:5c:c3:a7:f6:d0:34:ca:92:b1:52:f5: + 3a:27:3a:99:a3:74:66:f2:26:cc:54:50:f6:23:cb: + 44:39:e9:a7:ab:b5:c9:38:d4:d6:ae:53:ca:fc:9c: + f4:a9:38:58:3a:e8:bd:88:34:ba:4d:7b:5c:f9:e6: + 9c:b3:4d:2d:38:9c:a2:f7:85:da:3c:91:64:ae:83: + fe:07:d7:f0:d4:5c:73:5f:cc:0c:48:17:26:f9:f9: + 30:4f:f3:6c:67:7b:cc:9c:89:4e:ec:fd:fc:45:45: + e4:3f:1d:31:32:3a:9e:f1:21:79:1a:01:1f:72:4d: + 56:80:e7:a0:c8:31:9f:6b:7f:22:a0:d1:64:80:60: + 49:c8:4d:05:43:27:ed:ce:08:71:63:49:7c:84:44: + d1:a9:27:44:bc:63:50:53:4c:51:41:00:9e:86:78: + e0:67:b3:bf:f9:1c:6b:be:00:b4:11:73:11:a5:c4: + 8f:96:c2:40:d9:58:5d:0e:68:ae:d5:68:08:a0:98: + 02:05:ec:c4:88:57:dd:48:90:99:cc:a7:19:24:cc: + c7:eb:15:47:43:9f:07:34:ac:a5:93:40:87:d9:a4: + 59:c0:df:9c:14:55:37:f0:22:2f:a1:93:65:f9:8d: + 05:46:6e:30:e7: + +public exponent: + 01:00:01: + +private exponent: + 4c:60:ed:28:d4:d2:1c:65:16:6a:36:df:2e:28:cb: + fa:75:5d:5a:84:9f:75:7f:31:5e:c3:51:ee:00:a7: + f0:d1:b0:27:b5:21:01:e3:68:ef:72:26:a0:50:d4: + 02:9f:ef:91:ed:ab:0b:4b:21:c6:19:30:22:74:da: + 3b:b4:d5:d4:5b:fc:4c:39:d0:1f:ee:8d:c6:54:20: + 23:03:db:6a:ab:fa:e0:19:aa:2b:25:4f:5d:8f:e6: + 4a:fb:8c:84:3e:8e:db:40:3d:d3:4c:c5:7b:fc:6f: + df:30:00:c2:99:9a:4d:d5:95:c1:07:b2:d0:a4:60: + 1a:c0:53:22:1e:b2:d3:72:04:77:f2:93:e4:2c:f1: + 8c:4a:3b:48:3f:8b:30:6e:67:1f:48:13:69:76:ce: + bf:11:31:92:c3:66:2e:b4:8c:05:9b:c7:92:92:87: + 74:d9:90:a1:63:b8:5f:41:a2:7b:69:5e:f0:d4:ca: + f8:f0:0d:39:17:27:1f:be:7a:44:0f:99:d7:db:0e: + 91:fc:8c:bc:4f:42:aa:d0:ef:2d:3d:95:96:cd:7c: + 08:b2:b3:77:80:fd:c8:cc:78:62:a3:28:8e:95:de: + 65:63:83:fb:c9:0e:12:d9:d1:a4:6c:de:2b:b8:1e: + 11:33:a3:98:22:55:17:85:17:f4:a5:64:ab:53:24: + 9d:44:e2:c1:ec:b7:1d:1e:bb:a8:38:62:e3:87:49: + 75:42:3a:08:da:25:94:4b:6e:ec:a6:12:c8:e0:fa: + 57:25:5d:f9:cc:6c:4c:d0:6b:b8:d0:31:c9:6b:86: + 28:81:e0:21: + +prime1: + 00:fe:2d:10:cc:db:19:c0:8c:63:74:98:e3:bc:ee: + 73:7b:c1:18:48:eb:31:f0:29:6c:91:56:50:0a:36: + 54:43:ca:aa:fb:48:f7:5a:2c:fe:8a:11:d7:56:9e: + e9:76:03:8d:b5:a0:15:c0:b6:c3:69:23:ab:52:35: + e5:bd:7a:d3:3a:d1:4d:fd:8f:a6:01:db:d0:d2:19: + 5f:60:e5:f6:1c:de:26:54:f1:4a:b2:26:08:b8:93: + 95:1f:52:0e:d7:66:13:27:12:e3:01:d6:c0:90:da: + 63:a2:2b:d2:4a:91:85:90:6f:fb:ff:e8:b9:fc:88: + 6e:ff:50:95:73:dd:6f:e5:03:ad:fa:cd:82:4e:aa: + 02:00:f7:5d:e0:fa:0e:f4:2f:05:9f:06:3e:fc:bb: + d5:bf:af: + +prime2: + 00:cb:4d:f5:e1:67:58:9c:2a:f7:19:20:6a:e3:0a: + dd:b9:35:df:c5:eb:3d:40:95:1d:ca:7a:83:6b:fc: + aa:22:91:94:98:a0:16:7e:68:48:8f:d1:db:88:62: + db:ac:e3:6f:5e:00:f1:29:8f:2d:3e:96:4f:c2:67: + ef:15:78:25:f7:78:04:b7:18:87:e6:16:e1:fb:12: + 1f:d4:e9:d8:63:70:8c:0d:96:ba:27:75:19:00:25: + dd:b1:c5:00:56:4b:96:2e:52:0a:dd:c6:c4:62:bb: + d2:24:20:f0:c2:bd:c1:41:e7:5f:8f:9f:db:93:1d: + fb:40:02:85:49:70:f3:eb:12:61:65:8f:92:b8:9a: + 9d:b6:8a:6e:78:8a:74:d8:49:e6:ad:1a:c4:9c:c9: + 07:f8:49: + +coefficient: + 53:f4:68:8c:8c:57:d8:ab:13:6c:2c:22:27:44:12: + 28:ae:b3:71:b6:d9:7f:c3:21:b1:f5:6f:fa:b3:70: + a6:64:54:4a:fe:cb:ed:22:af:76:2e:eb:05:b4:a8: + ed:50:93:ed:34:c7:90:9f:9f:0a:8c:69:5d:63:20: + 1f:52:f2:0d:18:59:df:b4:bb:67:c5:e2:b2:10:31: + be:4b:c6:07:a4:90:e9:50:8e:b3:0b:95:0a:e1:82: + ef:0f:3d:48:8f:e4:e5:12:a7:5c:12:89:0c:9b:34: + 6b:da:83:a4:b1:61:5d:58:9a:ac:44:f7:b2:b4:bf: + 7a:c6:ad:41:86:70:40:3a:71:20:30:35:a1:2d:8b: + 29:eb:1d:cf:c6:b5:c5:8a:55:29:7f:d4:98:91:76: + 4b:a1: + +exp1: + 79:8d:39:a4:8d:ff:01:ba:e1:71:08:10:98:f0:7b: + 9f:aa:17:20:00:01:f0:b5:0e:ab:6e:58:76:99:c6: + b0:68:c2:5d:cb:66:26:e4:af:91:7d:b8:ba:3e:e2: + ac:c2:44:49:a0:55:e6:c4:40:2d:0e:96:c6:88:e9: + e6:34:4f:c1:a8:08:a1:02:ca:43:c7:48:54:c1:37: + 80:92:58:a1:33:87:a7:45:81:10:32:ea:26:c2:c5: + 24:a6:4c:5c:ab:fe:ea:c7:b8:71:cf:ae:65:57:5b: + 20:59:ce:86:44:93:58:20:85:a5:bb:38:fe:50:8c: + ac:62:70:26:69:b6:32:12:11:68:88:51:11:a7:71: + af:de:9c:31:93:c4:04:f8:5b:ba:d1:f4:db:4e:44: + 89:17: + +exp2: + 48:1e:4f:aa:b5:ce:69:17:94:b0:05:1f:e5:8a:65: + 3c:de:2f:93:35:ef:74:89:71:17:f2:7d:cc:40:c4: + d9:9e:6a:e7:f9:62:01:55:5c:e8:27:b9:88:98:08: + f5:3b:78:b6:0f:ff:7c:8e:9d:ae:26:04:05:22:79: + 5d:54:51:a3:87:9f:a4:93:bf:21:8f:dc:7a:03:e3: + e6:d3:4d:3f:79:1d:35:74:d2:74:4c:c5:a1:97:cd: + 1c:d2:95:5c:07:54:2e:fa:4b:80:80:92:09:b4:36: + c7:3a:28:2d:ec:c2:31:6e:b2:27:70:bd:a3:62:6f: + 4e:35:96:b2:86:af:00:24:75:08:61:f5:da:26:7e: + eb:d2:0f:7e:13:1f:7f:da:37:4a:10:c4:ce:19:42: + 0a:81: + + +Public Key ID: 41:D1:DF:57:36:A3:05:0C:28:EF:AB:7A:38:D2:F4:6C:50:50:A7:79 +Public key's random art: ++--[ RSA 2432]----+ +| ..o+..o.. | +| . o+.. . +o| +| .o+E . .o.+| +| ..o ... .| +| . S . | +| o . | +| o = . | +| . + = . | +| ..=.. | ++-----------------+ + +-----BEGIN RSA PRIVATE KEY----- +MIIFegIBAAKCATEAydskAWynQHjFiqge8IkIzvpHZUB1iyqVLEDWk1I3D0ZakkZ+ +4p+2MklGvaf3HcBjnpnexL7UOIUx8OWO/Cu0XMOn9tA0ypKxUvU6JzqZo3Rm8ibM +VFD2I8tEOemnq7XJONTWrlPK/Jz0qThYOui9iDS6TXtc+eacs00tOJyi94XaPJFk +roP+B9fw1FxzX8wMSBcm+fkwT/NsZ3vMnIlO7P38RUXkPx0xMjqe8SF5GgEfck1W +gOegyDGfa38ioNFkgGBJyE0FQyftzghxY0l8hETRqSdEvGNQU0xRQQCehnjgZ7O/ ++RxrvgC0EXMRpcSPlsJA2VhdDmiu1WgIoJgCBezEiFfdSJCZzKcZJMzH6xVHQ58H +NKylk0CH2aRZwN+cFFU38CIvoZNl+Y0FRm4w5wIDAQABAoIBMExg7SjU0hxlFmo2 +3y4oy/p1XVqEn3V/MV7DUe4Ap/DRsCe1IQHjaO9yJqBQ1AKf75HtqwtLIcYZMCJ0 +2ju01dRb/Ew50B/ujcZUICMD22qr+uAZqislT12P5kr7jIQ+jttAPdNMxXv8b98w +AMKZmk3VlcEHstCkYBrAUyIestNyBHfyk+Qs8YxKO0g/izBuZx9IE2l2zr8RMZLD +Zi60jAWbx5KSh3TZkKFjuF9BontpXvDUyvjwDTkXJx++ekQPmdfbDpH8jLxPQqrQ +7y09lZbNfAiys3eA/cjMeGKjKI6V3mVjg/vJDhLZ0aRs3iu4HhEzo5giVReFF/Sl +ZKtTJJ1E4sHstx0eu6g4YuOHSXVCOgjaJZRLbuymEsjg+lclXfnMbEzQa7jQMclr +hiiB4CECgZkA/i0QzNsZwIxjdJjjvO5ze8EYSOsx8ClskVZQCjZUQ8qq+0j3Wiz+ +ihHXVp7pdgONtaAVwLbDaSOrUjXlvXrTOtFN/Y+mAdvQ0hlfYOX2HN4mVPFKsiYI +uJOVH1IO12YTJxLjAdbAkNpjoivSSpGFkG/7/+i5/Ihu/1CVc91v5QOt+s2CTqoC +APdd4PoO9C8FnwY+/LvVv68CgZkAy0314WdYnCr3GSBq4wrduTXfxes9QJUdynqD +a/yqIpGUmKAWfmhIj9HbiGLbrONvXgDxKY8tPpZPwmfvFXgl93gEtxiH5hbh+xIf +1OnYY3CMDZa6J3UZACXdscUAVkuWLlIK3cbEYrvSJCDwwr3BQedfj5/bkx37QAKF +SXDz6xJhZY+SuJqdtopueIp02EnmrRrEnMkH+EkCgZh5jTmkjf8BuuFxCBCY8Huf +qhcgAAHwtQ6rblh2mcawaMJdy2Ym5K+Rfbi6PuKswkRJoFXmxEAtDpbGiOnmNE/B +qAihAspDx0hUwTeAklihM4enRYEQMuomwsUkpkxcq/7qx7hxz65lV1sgWc6GRJNY +IIWluzj+UIysYnAmabYyEhFoiFERp3Gv3pwxk8QE+Fu60fTbTkSJFwKBmEgeT6q1 +zmkXlLAFH+WKZTzeL5M173SJcRfyfcxAxNmeauf5YgFVXOgnuYiYCPU7eLYP/3yO +na4mBAUieV1UUaOHn6STvyGP3HoD4+bTTT95HTV00nRMxaGXzRzSlVwHVC76S4CA +kgm0Nsc6KC3swjFusidwvaNib041lrKGrwAkdQhh9domfuvSD34TH3/aN0oQxM4Z +QgqBAoGYU/RojIxX2KsTbCwiJ0QSKK6zcbbZf8MhsfVv+rNwpmRUSv7L7SKvdi7r +BbSo7VCT7TTHkJ+fCoxpXWMgH1LyDRhZ37S7Z8XishAxvkvGB6SQ6VCOswuVCuGC +7w89SI/k5RKnXBKJDJs0a9qDpLFhXViarET3srS/esatQYZwQDpxIDA1oS2LKesd +z8a1xYpVKX/UmJF2S6E= +-----END RSA PRIVATE KEY----- diff --git a/tests2/certs/x509-server-cert.pem b/tests2/certs/x509-server-cert.pem new file mode 100644 index 00000000..e597402e --- /dev/null +++ b/tests2/certs/x509-server-cert.pem @@ -0,0 +1,23 @@ +-----BEGIN CERTIFICATE----- +MIID6jCCAqKgAwIBAgIIVOoLCjBx2XwwDQYJKoZIhvcNAQELBQAwMzENMAsGA1UE +AxMETWdldDENMAsGA1UECxMETWdldDETMBEGA1UEChMKcm9ja2RhYm9vdDAiGA8y +MDE1MDIyMjE2NTk1N1oYDzk5OTkxMjMxMjM1OTU5WjA4MRIwEAYDVQQDEwkxMjcu +MC4wLjExDTALBgNVBAsTBE1nZXQxEzARBgNVBAoTCnJvY2tkYWJvb3QwggFSMA0G +CSqGSIb3DQEBAQUAA4IBPwAwggE6AoIBMQDRsecbE8++eK1mxuxPOQdcGXWAsxuF +pCuLuLI3BPViQ63Kqy9Yy7Yt9oeuPJq4HI5W0w8EieBWbaONajs0w0cWIjvc31/E +IvTLBBHqYc6NoK0miScC3TQhRnvTSrJbl4CQ5H90Ri7ske6oAVMSDuUQF8+DQf+p +czLJ8tohsNjj2ASEtwiEAFXvMTI0bHYpbqvUgNR/hLFcXvXKattJVyjbKecZLGOJ +QqR27DspHT9az1s31wdaWbsaqiZky9PANx9mFxZpZGQJEoD23UTRSsZI3NYf/b0I +nTzkyJNubP+tkdyA6yhBAkb4i87FWkiHSwpVJk2vsZm5sKA1SzJiji7l9dUwMXmA +xTajnAI6N6F66MArfPdab9SRFkRNAHVwt1aYp3vjgOzKpRRnu0LDyqrXAgMBAAGj +gZgwgZUwDAYDVR0TAQH/BAIwADAfBgNVHREEGDAWggkxMjcuMC4wLjGCCWxvY2Fs +aG9zdDATBgNVHSUEDDAKBggrBgEFBQcDATAPBgNVHQ8BAf8EBQMDB6AAMB0GA1Ud +DgQWBBShB4xj2jWSG4m1m7gPRKAWKujGPjAfBgNVHSMEGDAWgBRxBpzKT6H76Wuf +ScE3SHGdQEXNwzANBgkqhkiG9w0BAQsFAAOCATEAKUVQOzo8UV9zSaPL/LqrWwaP +C0JP/ncxqtRLVBc6a67Oe8I20nRK1S3TiSJZAKC2BSeyYKsYUV5/NdL7KhvF5Pjz +vuHC5PB7SCFSZrD4axorFsr3oHBlXmBIEbvkotOokz0yWiScquvcSrYeQRRGVpMp ++an2b2UOekcxc1xwozre1j7BDw3V6xc5UdeDxqqdG0KptRSSBRdsF9tPKO50+URn +JUg8Smosuq32EH6dJuTLDocl5mynz+lGLy/828RLZgIFSSacl/ts8T95D3DjL1+b +iHDfQfqcjwkb5m1VusG1k55HWTnwuFlj2bvve1txXECUngMz9MMfOK/+Ly6ACrt0 +jDH07vJ9VtgWFREDGvj/e1tsk8sWMnK2LlggKWayx/COOMgWuv9SdEyZTlumZQ== +-----END CERTIFICATE----- diff --git a/tests2/certs/x509-server-crl.pem b/tests2/certs/x509-server-crl.pem new file mode 100644 index 00000000..29b9edc1 --- /dev/null +++ b/tests2/certs/x509-server-crl.pem @@ -0,0 +1,13 @@ +-----BEGIN X509 CRL----- +MIICBzCBwAIBATANBgkqhkiG9w0BAQsFADAzMQ0wCwYDVQQDEwRNZ2V0MQ0wCwYD +VQQLEwRNZ2V0MRMwEQYDVQQKEwpyb2NrZGFib290GA8yMDE1MDIyMjE3MDM1MVoY +Dzk5OTkxMjMxMjM1OTU5WjAdMBsCCFTqCwowcdl8GA8yMDE1MDIyMjE3MDM1MVqg +NjA0MB8GA1UdIwQYMBaAFHEGnMpPofvpa59JwTdIcZ1ARc3DMBEGA1UdFAQKAghU +6gv5MFwyuDANBgkqhkiG9w0BAQsFAAOCATEASyaCHchc7sIQDN41351nGfhsCnOS +rno2X1ivJQ1M987KwODfl+s1Ecrkxp20VijBmt9FJ1gqqLSypB/cUKz7QC3WzRPo +buKdio66a2e+LN8+7kXSfwt4wUlpR3BXTOmlZVDnLBA8PCtjnPHwuY82Y4Cpg38R +yfSRmLtenSCVZk/SraVQ6c6kvKbgCM9kR/7/gMrZyW6SFLgXVFDAe6ZNSSALfgjC +zg3He+3a0+upvwghS3YZZrxYBzbzr6s+RisTVF9bhg18LiHtEV5IlZJJPK1Lfdur +5snpuXK7fDD1mTd0bHlneE8cnMg7c7UHNudXgDdoJH+aFay/hVQkFoVGlNtmjJjS ++yUOXhHvQDe2LWLVu2bYWjny99cQDYV7MR8NuBQpY2etPIHlldShhnj6BQ== +-----END X509 CRL----- diff --git a/tests2/certs/x509-server-key.pem b/tests2/certs/x509-server-key.pem new file mode 100644 index 00000000..611d1f5f --- /dev/null +++ b/tests2/certs/x509-server-key.pem @@ -0,0 +1,165 @@ +Public Key Info: + Public Key Algorithm: RSA + Key Security Level: Normal (2432 bits) + +modulus: + 00:d1:b1:e7:1b:13:cf:be:78:ad:66:c6:ec:4f:39: + 07:5c:19:75:80:b3:1b:85:a4:2b:8b:b8:b2:37:04: + f5:62:43:ad:ca:ab:2f:58:cb:b6:2d:f6:87:ae:3c: + 9a:b8:1c:8e:56:d3:0f:04:89:e0:56:6d:a3:8d:6a: + 3b:34:c3:47:16:22:3b:dc:df:5f:c4:22:f4:cb:04: + 11:ea:61:ce:8d:a0:ad:26:89:27:02:dd:34:21:46: + 7b:d3:4a:b2:5b:97:80:90:e4:7f:74:46:2e:ec:91: + ee:a8:01:53:12:0e:e5:10:17:cf:83:41:ff:a9:73: + 32:c9:f2:da:21:b0:d8:e3:d8:04:84:b7:08:84:00: + 55:ef:31:32:34:6c:76:29:6e:ab:d4:80:d4:7f:84: + b1:5c:5e:f5:ca:6a:db:49:57:28:db:29:e7:19:2c: + 63:89:42:a4:76:ec:3b:29:1d:3f:5a:cf:5b:37:d7: + 07:5a:59:bb:1a:aa:26:64:cb:d3:c0:37:1f:66:17: + 16:69:64:64:09:12:80:f6:dd:44:d1:4a:c6:48:dc: + d6:1f:fd:bd:08:9d:3c:e4:c8:93:6e:6c:ff:ad:91: + dc:80:eb:28:41:02:46:f8:8b:ce:c5:5a:48:87:4b: + 0a:55:26:4d:af:b1:99:b9:b0:a0:35:4b:32:62:8e: + 2e:e5:f5:d5:30:31:79:80:c5:36:a3:9c:02:3a:37: + a1:7a:e8:c0:2b:7c:f7:5a:6f:d4:91:16:44:4d:00: + 75:70:b7:56:98:a7:7b:e3:80:ec:ca:a5:14:67:bb: + 42:c3:ca:aa:d7: + +public exponent: + 01:00:01: + +private exponent: + 72:42:5b:c9:17:4c:75:5e:d0:2d:56:6a:e0:e8:14: + 28:8c:fe:c7:b7:d0:61:4b:89:26:c2:e6:e8:af:dc: + fd:44:1f:68:75:4a:81:39:ce:f4:d0:86:31:dc:77: + f9:a6:25:b1:0d:a3:fb:37:1d:74:3a:9d:89:aa:be: + c4:0b:3b:aa:c5:d0:94:93:6a:5d:37:26:e7:90:3a: + 2a:da:4c:70:43:82:d5:a2:9a:0d:27:77:06:42:9f: + aa:0b:e3:8f:a0:c7:bf:2b:a2:7f:3a:d6:ca:b4:e1: + b3:cd:b4:f3:fc:05:b8:75:20:ef:46:81:06:55:ec: + f0:b9:51:3e:56:5c:78:19:f6:ac:52:07:63:d5:c2: + fd:68:73:10:b9:a0:d1:06:aa:be:49:cc:80:07:4f: + 95:22:74:6f:a4:bc:6d:46:65:89:49:5e:22:4a:d0: + eb:7c:a6:63:e8:e2:f7:27:7a:a0:05:be:29:32:28: + c1:3b:27:80:3d:f6:b9:09:cb:1d:d3:68:16:a1:16: + 1c:cc:ba:af:fe:f1:90:b3:71:48:4f:76:17:81:b0: + b4:b4:72:b8:b4:5d:11:f3:a3:fa:e2:45:8c:cc:b9: + ed:3e:2c:3b:85:fc:ef:1e:6f:e1:3b:c9:c0:da:ed: + 6c:cb:d7:90:b4:28:bf:a8:3e:cd:d4:2e:b7:73:25: + 58:ef:0d:9c:b9:15:27:c0:53:42:81:82:2b:6b:89: + 94:3b:63:f5:8c:37:74:33:c0:1a:bd:b2:d0:30:d5: + f8:75:b5:f6:78:86:ea:3e:70:a0:0f:c5:36:b4:cf: + 29:2f:91:a1: + +prime1: + 00:ef:34:77:5b:e2:46:2c:80:ce:e6:20:46:9d:33: + d0:81:7d:33:02:bb:c9:12:a0:c2:2f:ba:30:32:95: + a3:db:a7:27:af:35:ee:59:70:0a:09:22:1a:f4:96: + 37:7d:fa:54:fb:46:4e:f7:1b:b9:50:4d:e5:05:16: + 71:9b:75:3b:fc:ae:a7:9c:05:3d:62:45:0a:d3:01: + a7:22:3c:49:ad:fe:1c:be:84:84:7b:f3:45:a4:54: + 98:f7:1d:bc:67:29:1d:4e:01:6b:7d:a1:82:26:32: + 12:c2:a7:fb:1c:0a:c6:1e:10:5f:f6:a7:e2:19:7b: + 05:39:26:6e:77:4d:e3:e9:62:53:ed:ad:7e:6a:16: + b6:a0:f0:5b:2c:8c:46:2e:98:ab:2c:e5:71:67:00: + c2:c7:69: + +prime2: + 00:e0:6b:03:ff:f8:07:75:ae:56:e0:f1:b8:cd:8e: + cc:c0:7c:54:bc:43:19:dd:62:a9:10:07:01:37:6a: + 91:e1:43:18:51:05:f1:0c:33:c4:f3:e5:d5:c2:52: + 79:56:33:b8:4e:72:f0:80:b2:2a:32:9d:63:25:af: + 32:77:98:00:d1:22:86:25:f2:86:74:91:19:eb:fd: + 85:e1:63:43:2e:c5:54:d8:d3:74:7f:0c:ae:b5:e8: + 83:53:ed:97:97:28:d5:be:94:b7:d4:36:b4:0d:51: + a0:b2:fc:b3:8c:70:8d:46:a2:e2:c6:11:ed:75:fe: + 37:f9:a8:4d:fe:a9:94:37:d0:72:6f:fc:bf:aa:ad: + 68:56:f0:ed:f1:86:04:a0:4c:27:6e:89:c5:cb:6e: + 63:d8:3f: + +coefficient: + 00:eb:8e:c0:fe:3e:81:67:64:61:a1:97:01:94:99: + 35:86:d5:8e:c4:60:00:90:f9:6c:ff:f3:b1:55:60: + b8:2f:60:e8:6d:0b:ee:15:7a:7d:f3:6e:42:7c:39: + 91:a6:57:59:39:86:3e:da:73:db:e0:54:ac:5d:81: + 31:23:9b:d3:fc:a0:9a:8b:9a:7f:67:63:d8:eb:f4: + 37:a4:13:46:d8:4c:44:1f:c7:28:e4:c5:ba:2c:78: + a1:5c:6a:cc:65:84:a9:1e:a1:6d:c4:62:57:3c:a8: + e5:42:ed:a4:ec:b0:11:91:5f:12:55:67:f4:9d:19: + 6f:36:2f:e4:3b:08:6b:e1:68:b6:d1:26:b2:7e:a8: + 60:04:8f:7b:0b:ca:2c:98:d5:c9:10:94:ab:d5:99: + eb:d2:31: + +exp1: + 1b:62:a7:53:96:a9:30:09:23:26:c7:85:2e:14:33: + 87:cf:9c:9a:70:83:49:a5:ab:f5:a8:dc:41:be:4d: + ff:24:b8:ef:5f:3e:45:71:05:45:1c:69:77:9d:07: + 07:5e:34:82:7b:ff:28:5d:3d:2f:0b:6b:ef:d4:2c: + f7:7e:49:7a:d9:48:09:1d:b4:74:5e:b1:29:8d:23: + e4:50:80:a2:f1:d7:ba:9c:13:4a:d9:84:1c:97:2e: + d8:03:c8:81:0a:fc:f6:e4:44:b9:22:57:73:26:02: + 6d:d4:ab:73:ff:6b:c5:1f:5c:cd:31:55:3a:53:92: + 3a:83:c2:db:d7:c8:02:fd:25:dc:ad:23:2e:e4:20: + ce:76:16:0a:18:99:24:56:88:2a:60:ae:45:fb:99: + 51:19: + +exp2: + 6d:f6:e2:39:dd:de:41:e2:d0:7d:5e:d4:90:1c:e5: + e5:77:c6:c9:8d:13:b2:70:32:a9:40:d5:6e:c3:10: + 82:51:af:2b:9c:7e:b5:dc:f4:28:12:b9:c0:83:4b: + 23:5b:2a:77:7e:48:ac:b7:20:88:36:a8:ab:81:82: + 78:29:8a:54:ef:d6:cd:e7:5d:cc:e6:80:ce:2b:27: + 1b:fe:d8:9f:a5:5f:e2:f3:12:45:63:00:84:f0:4e: + d1:a4:3d:40:7b:68:e8:fe:d4:68:ee:f9:21:01:9b: + 7d:b8:e7:7d:ec:74:bd:64:f9:3b:d6:f3:05:7b:31: + 10:6b:50:f4:75:41:c4:6b:a6:77:8b:60:9b:90:66: + ed:1b:17:6c:de:9f:8b:b0:65:2d:fb:e2:68:c1:49: + b9:5f: + + +Public Key ID: A1:07:8C:63:DA:35:92:1B:89:B5:9B:B8:0F:44:A0:16:2A:E8:C6:3E +Public key's random art: ++--[ RSA 2432]----+ +|.. . | +|+..o * | +|=.o X = . | +|=. = O + . | +| ++ = . S | +|o. . . | +| Eo | +| .o | +| . | ++-----------------+ + +-----BEGIN RSA PRIVATE KEY----- +MIIFewIBAAKCATEA0bHnGxPPvnitZsbsTzkHXBl1gLMbhaQri7iyNwT1YkOtyqsv +WMu2LfaHrjyauByOVtMPBIngVm2jjWo7NMNHFiI73N9fxCL0ywQR6mHOjaCtJokn +At00IUZ700qyW5eAkOR/dEYu7JHuqAFTEg7lEBfPg0H/qXMyyfLaIbDY49gEhLcI +hABV7zEyNGx2KW6r1IDUf4SxXF71ymrbSVco2ynnGSxjiUKkduw7KR0/Ws9bN9cH +Wlm7GqomZMvTwDcfZhcWaWRkCRKA9t1E0UrGSNzWH/29CJ085MiTbmz/rZHcgOso +QQJG+IvOxVpIh0sKVSZNr7GZubCgNUsyYo4u5fXVMDF5gMU2o5wCOjeheujAK3z3 +Wm/UkRZETQB1cLdWmKd744DsyqUUZ7tCw8qq1wIDAQABAoIBMHJCW8kXTHVe0C1W +auDoFCiM/se30GFLiSbC5uiv3P1EH2h1SoE5zvTQhjHcd/mmJbENo/s3HXQ6nYmq +vsQLO6rF0JSTal03JueQOiraTHBDgtWimg0ndwZCn6oL44+gx78ron861sq04bPN +tPP8Bbh1IO9GgQZV7PC5UT5WXHgZ9qxSB2PVwv1ocxC5oNEGqr5JzIAHT5UidG+k +vG1GZYlJXiJK0Ot8pmPo4vcneqAFvikyKME7J4A99rkJyx3TaBahFhzMuq/+8ZCz +cUhPdheBsLS0cri0XRHzo/riRYzMue0+LDuF/O8eb+E7ycDa7WzL15C0KL+oPs3U +LrdzJVjvDZy5FSfAU0KBgitriZQ7Y/WMN3QzwBq9stAw1fh1tfZ4huo+cKAPxTa0 +zykvkaECgZkA7zR3W+JGLIDO5iBGnTPQgX0zArvJEqDCL7owMpWj26cnrzXuWXAK +CSIa9JY3ffpU+0ZO9xu5UE3lBRZxm3U7/K6nnAU9YkUK0wGnIjxJrf4cvoSEe/NF +pFSY9x28ZykdTgFrfaGCJjISwqf7HArGHhBf9qfiGXsFOSZud03j6WJT7a1+aha2 +oPBbLIxGLpirLOVxZwDCx2kCgZkA4GsD//gHda5W4PG4zY7MwHxUvEMZ3WKpEAcB +N2qR4UMYUQXxDDPE8+XVwlJ5VjO4TnLwgLIqMp1jJa8yd5gA0SKGJfKGdJEZ6/2F +4WNDLsVU2NN0fwyuteiDU+2XlyjVvpS31Da0DVGgsvyzjHCNRqLixhHtdf43+ahN +/qmUN9Byb/y/qq1oVvDt8YYEoEwnbonFy25j2D8CgZgbYqdTlqkwCSMmx4UuFDOH +z5yacINJpav1qNxBvk3/JLjvXz5FcQVFHGl3nQcHXjSCe/8oXT0vC2vv1Cz3fkl6 +2UgJHbR0XrEpjSPkUICi8de6nBNK2YQcly7YA8iBCvz25ES5IldzJgJt1Ktz/2vF +H1zNMVU6U5I6g8Lb18gC/SXcrSMu5CDOdhYKGJkkVogqYK5F+5lRGQKBmG324jnd +3kHi0H1e1JAc5eV3xsmNE7JwMqlA1W7DEIJRryucfrXc9CgSucCDSyNbKnd+SKy3 +IIg2qKuBgngpilTv1s3nXczmgM4rJxv+2J+lX+LzEkVjAITwTtGkPUB7aOj+1Gju ++SEBm324533sdL1k+TvW8wV7MRBrUPR1QcRrpneLYJuQZu0bF2zen4uwZS374mjB +SblfAoGZAOuOwP4+gWdkYaGXAZSZNYbVjsRgAJD5bP/zsVVguC9g6G0L7hV6ffNu +Qnw5kaZXWTmGPtpz2+BUrF2BMSOb0/ygmouaf2dj2Ov0N6QTRthMRB/HKOTFuix4 +oVxqzGWEqR6hbcRiVzyo5ULtpOywEZFfElVn9J0ZbzYv5DsIa+FottEmsn6oYASP +ewvKLJjVyRCUq9WZ69Ix +-----END RSA PRIVATE KEY----- diff --git a/tests2/files/contact.html b/tests2/files/contact.html new file mode 100644 index 00000000..4aadf4f2 --- /dev/null +++ b/tests2/files/contact.html @@ -0,0 +1,785 @@ +<!doctype html> +<!--[if lt IE 7 ]> <html class="no-js ie6" lang="en"> <![endif]--> +<!--[if IE 7 ]> <html class="no-js ie7" lang="en"> <![endif]--> +<!--[if IE 8 ]> <html class="no-js ie8" lang="en"> <![endif]--> +<!--[if (gte IE 9)|!(IE)]><!--> <html class="no-js"> <!--<![endif]--> +<head> + <title>Linux Security Contacts</title> + <meta name="description" content="SUSE Linux Enterprise security contact information and encryption keys" /> + <meta name="keywords" content="suse, security, contact, encryption keys" /> + + <meta charset="utf-8"> +<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"> +<meta name="viewport" content="width=device-width, initial-scale=1.0"> + +<link rel="shortcut icon" href="/common/img/favicon.gif"> +<link rel="apple-touch-icon" href="/common/img/apple-touch-iphone.png"> +<link rel="apple-touch-icon" sizes="72x72" href="/common/img/apple-touch-ipad.png"> +<link rel="apple-touch-icon" sizes="114x114" href="/common/img/apple-touch-iphone4.png"> +<link rel="stylesheet" href="/common/inc/css/main.css?v=11"> + +<!-- Grab Google CDN's jQuery, with a protocol relative URL; fall back to local if necessary --> +<script src="//ajax.googleapis.com/ajax/libs/jquery/1.5.1/jquery.min.js"></script> +<script>window.jQuery || document.write("<script src='/common/inc/js/jquery-1.5.1.min.js'><\/script>")</script> + +<!-- JS that is necessary for page load. All other JS is included in ftr_js.html --> +<script src="/common/inc/js/core.js?v=1"></script> +<script src="/common/inc/js/modernizr-1.7.min.js"></script> + +<!-- Typekit --> +<script type="text/javascript" src="http://use.typekit.com/oar0gpe.js"></script> +<script type="text/javascript">try{Typekit.load();}catch(e){}</script> + +<script type="text/javascript"> + document.write('<script type="text/javascript" src="http://www.suse.com/common/util/geophone.php?co='+user_country_code+'"><\/script>'); +</script> + +<!-- Foresee Survey --> + + <script type="text/javascript" src="/common/inc/foresee/foresee-trigger.js"></script> + + +</head> +<body> +<div id="container"> + <header> + <div class="wrap"> + <!-- <p class="portal"><a href="#"><strong>SuSE</strong> Customer Portal</a></p> --> + <div> + <div id="search"> + <form action="/SearchUI/query" method="get"> + <label for="q">Search</label> + <input type="text" name="term" value="" id="q"> + <input type="submit" name="submit" value="" id="q_submit"> + </form> + </div> + </div> + <div id="logo"><a href="/">SUSE</a></div> + <ul id="nav"> + <li id="nav_solutions"><a href="/solutions/">Solutions</a> + <div class="nav_sub"> + <div class="nav_sub_contents"> + <div class="col col_two"> + <p class="nav_subheading"><a href="/solutions/platform.html">Platform Solutions</a></p> + <ul> + <li><a href="/solutions/platform.html#server">Server</a></li> + <li><a href="/solutions/platform.html#desktop">Desktop</a></li> + <li><a href="/solutions/platform.html#cloud">Cloud Computing</a></li> + <li><a href="/solutions/platform.html#virtualization">Virtualization</a></li> + </ul> +</div> +<div class="col col_two"> + <p class="nav_subheading"><a href="/solutions/industry.html">Industry Solutions</a></p> + <ul> + <li><a href="/solutions/industry.html#retail">Retail</a></li> + <li><a href="/solutions/industry.html#healthcare"><span>Healthcare</span></a></li> + <li><a href="/solutions/industry.html#manufacturing">Manufacturing</a></li> + <li><a href="/solutions/industry.html#government">Government</a></li> + <li><a href="/solutions/industry.html#banking">Banking & Finance</a></li> + </ul> +</div> +<div class="clr"></div> + + </div> + </div> + </li> + <li id="nav_products"><a href="/products/">Products & Services</a> + <div class="nav_sub"> + <div class="nav_sub_contents"> + <div class="col col_four"> + <p class="nav_subheading">Server</p> + <ul> + <li><a href="/products/server/">SUSE Linux Enterprise Server</a></li> + <li><a href="/products/systemz/">SUSE Linux Enterprise Server for System z</a></li> + <li><a href="/products/expandedsupport/">SUSE Linux Enterprise Server with Expanded Support</a></li> + <li><a href="/products/sles-for-sap/">SUSE Linux Enterprise Server for SAP Applications</a></li> + <li><a href="/products/linuxpointofservice/">SUSE Linux Enterprise Point of Service</a></li> + </ul> +</div> +<div class="col col_four"> + <p class="nav_subheading">OEM and Desktop</p> + <ul> + <li><a href="/partners/alliance-partners/vmware/">SUSE Linux Enterprise Server for VMware</a></li> + <li><a href="http://aws.amazon.com/suse/">SUSE Linux Enterprise Server for Amazon EC2</a></li> + <li><a href="/products/desktop/">SUSE Linux Enterprise Desktop</a></li> + <li><a href="http://www.novell.com/products/libreoffice/">LibreOffice</a></li> + </ul> +</div> +<div class="col col_four"> + <p class="nav_subheading">Extensions</p> + <ul> + <li><a href="/products/highavailability/">SUSE Linux Enterprise High Availability Extension</a></li> + <li><a href="/products/realtime/">SUSE Linux Enterprise Real Time Extension</a></li> + <li><a href="/products/vmdriverpack/">SUSE Linux Enterprise Virtual Machine Driver Pack</a></li> + <li><a href="http://www.novell.com/products/sle-management-pack/">SUSE Linux Enterprise Management Pack for System Center Operations Manager R2 2007</a></li> + </ul> +</div> +<div class="col col_four"> + <p class="nav_subheading">Management and Services</p> + <ul> + <li><a href="/products/suse-manager/">SUSE Manager</a></li> + <li><a href="/products/susestudio/">SUSE Studio</a></li> + <li><a href="/support/">Support</a></li> + <li><a href="/training/">Training and Certification</a></li> + <li><a href="http://www.novell.com/consulting/">Consulting</a></li> + </ul> +</div> +<div class="clr"></div> + + </div> + </div> + </li> + <li id="nav_support"><a href="/support/">Support</a> + <div class="nav_sub"> + <div class="nav_sub_contents"> + <div class="col col_five"> + <p class="nav_subheading"><a href="/support/">Self Support</a></p> + <ul> + <li><a href="/support/kb/">Knowledgebase</a></li> + <li><a href="http://support.novell.com/advisor/index.html">Novell Support Advisor</a></li> + <li><a href="http://forums.suse.com">Discussion Forums</a></li> + <li><a href="/documentation/">Documentation</a></li> + <li><a href="/releasenotes/">Release Notes</a></li> + <li><a href="/support/">Support by Product</a></li> + <li><a href="https://secure-www.novell.com/center/regadmin/jsps/activate_app.jsp">Activate My Product</a></li> + <li><a href="http://support.novell.com/subscriptions/index.html">Technical Subscriptions</a></li> + <li><a href="/security/">Get Security Reports</a></li> + </ul> +</div> +<div class="col col_five"> + <p class="nav_subheading"><a href="/support/programs.html">Support Programs</a></p> + <ul> + <li><a href="http://support.novell.com/partner_services.html">Support from Partner</a></li> + <li><a href="http://support.novell.com/contact/index.html">Open Service Request</a></li> + <li><a href="/support/programs.html">SUSE Support Programs</a></li> + <li><a href="http://support.novell.com/lifecycle/index.html">Product Support Lifecycle</a></li> + <li><a href="http://support.novell.com/chat/general">Chat with Us (Non-technical Questions)</a></li> + </ul> +</div> +<div class="col col_five"> + <p class="nav_subheading">Participate</p> + <ul> + <li><a href="http://support.novell.com/additional/bugreport.html">Report a Bug</a></li> + <li><a href="http://www.novell.com/communities/node/1394/how-submit-content">Submit Tips, Tricks & Tools</a></li> + <li><a href="http://support.novell.com/enhancement/index.html">Request Product Enhancement</a></li> + <li><a href="http://support.novell.com/security-alerts/index.html">Report Software Vulnerability</a></li> + <li><a href="http://www.novell.com/beta/index.jsp">Beta Test</a></li> + </ul> +</div> +<div class="col col_five"> + <p class="nav_subheading"><a href="/download-linux/">Download</a></p> + <ul> + <li><a href="http://support.novell.com/patches.html">Patches</a></li> + <li><a href="http://download.novell.com/">Products</a></li> + <li><a href="http://drivers.suse.com/">Drivers</a></li> + <li><a href="http://beta.novell.com/">Beta</a></li> + <li><a href="http://www.novell.com/communities/coolsolutions/tools">Cool Tools</a></li> + </ul> +</div> +<div class="col col_five"> + <p class="nav_subheading"><a href="https://secure-www.novell.com/center/regadmin/jsps/home_app.jsp">Customer Center</a></p> + <ul> + <li><a href="https://secure-www.novell.com/center/regadmin/jsps/profile_app.jsp">My Profile</a></li> + <li><a href="https://secure-www.novell.com/center/regadmin/jsps/sub_app.jsp?topic=list&clearFilter=true&clearGroupId=true">My Products</a></li> + <li><a href="https://secure-www.novell.com/center/eservice/">My Support</a></li> + <li><a href="https://secure-www.novell.com/center/trnsrv">My Training</a></li> + <li><a href="http://support.novell.com/contact/index.html">Open Service Request</a></li> + </ul> +</div> +<div class="clr"></div> + + </div> + </div> + </li> + <li id="nav_partners"><a href="/partners/">Partners</a> + <div class="nav_sub"> + <div class="nav_sub_contents"> + <div class="col col_four"> + <p class="nav_subheading"><a href="/partners">Partner with SUSE</a></p> + <ul> + <li><a href="/partners/solution/">Solution Provider & System Integrator</a></li> + <li><a href="/partners/ihv/">Hardware Vendor</a></li> + <li><a href="/partners/isv/">Software Vendor</a></li> + <li><a href="https://www.partnernetprogram.com/program/commercial-training/suse.html">Commercial Training Partner</a></li> + <li><a href="https://www.partnernetprogram.com/program/academic-training/suse.html">Academic Training Partner</a></li> + <li><a href="https://www.partnernetprogram.com/program/cloud-service-provider/suse.html">Cloud Service Provider</a></li> + </ul> +</div> +<div class="col col_four"> + <p class="nav_subheading"><a href="http://www.novell.com/site/partners/protected/index.page">PartnerNet</a></p> + <ul> + <li><a href="http://www.novell.com/site/partners/protected/index.page">PartnerNet Login</a></li> + <li><a href="http://www.novell.com/communities/partners/">PartnerNet Community</a></li> + <li><a href="http://www.novell.com/site/partners/protected/enablement/datacenter/enterpriselinuxservers/index.page">Enablement Central</a></li> + </ul> +</div> +<div class="col col_four"> + <p class="nav_subheading"><a href="http://www.novell.com/partnerlocator/">Find a Partner</a></p> + <ul> + <li><a href="http://www.novell.com/partnerlocator/">Partner Locator</a></li> + <li><a href="/partner/isv/isvcatalog">SUSE Linux Enterprise ISV Catalog</a></li> + <li><a href="/partners/alliance-partners/">Alliance Partners</a></li> + </ul> +</div> +<div class="col col_four"> + <p class="nav_subheading"><a href="/partners/isv/#suse_phone">Developers</a></p> + <ul> + <li><a href="http://developer.novell.com/devnet/yes/">YES Certified Program</a></li> + <li><a href="http://www.novell.com/communities/developers/">Developer Community</a></li> + </ul> +</div> +<div class="clr"></div> + + </div> + </div> + </li> + <li id="nav_community"><a href="/communities/">Community</a> + <div class="nav_sub"> + <div class="nav_sub_contents"> + <div class="col col_one"> + <p class="nav_subheading"><a href="/communities/">Community</a></p> + <ul> + <li><a href="/communities/#communities_user">User Communities</a></li> + <li><a href="/communities/#communities_social">Social Networks</a></li> + <li><a href="/communities/#communities_opensource">Open Source</a></li> + </ul> +</div> +<div class="clr"></div> + + </div> + </div> + </li> + <li id="nav_dl" class="highlight"><a href="/download-linux/">Free Downloads</a></li> + <li id="nav_shop" class="highlight"><a href="http://shop.novell.com/store/novell/DisplayCategoryProductListPage/categoryID.1581900">Shop</a></li> + </ul> + <div class="clr"></div> + </div> +</header> + + <div id="main" role="main"> + <div class="longtail tier4"> + <div id="content"> + <div class="wrap"> + <div class="share"> + <div class="post-share-links"> + <ul> + <li><a title="share on Facebook" onclick="return sharePost('facebook',window.location.href,document.title);" href="#" class="post-share-link-facebook">Facebook</a></li> + <li><a title="share on Twitter" onclick="return sharePost('twitter',window.location.href,document.title);" href="#" class="post-share-link-twitter">Twitter</a></li> + <li><a title="share in email" onclick="emailFriendPost(window.location.href); return false" href="#" class="post-share-link-email">E-mail</a></li> + </ul> +</div> +<p class="social"> + <a onclick="return false;" href="#" class="share_btn social_btns"> + + Share + + <img alt="" src="/common/img/social/share_icon.png"></a> +</p> + </div> + <h1>SUSE Security Contacts</h1> + <div class="content_left"> + <p class="subtitle">To contact the SUSE Security Team, write email to + <ul> + <li><a href="mailto:security@suse.de">security@suse.com</a></li> + <li><a href="mailto:security@suse.de">security@suse.de</a></li> + </ul> + <p>We encourage people who wish to contact SUSE Security to use mail encryption. Our key is:</p> + + <p>3D25D3D9 1999-03-06 SUSE Security Team <security suse.de><br /> + Key fingerprint = 73 5F 2E 99 DF DB 94 C4 8F 5A A3 AE AF 22 F2 D5</p> + <p>The key is listed below in ASCII encoded form.</p> +<pre> +-----BEGIN PGP PUBLIC KEY BLOCK----- +Version: GnuPG v1.0.6 (GNU/Linux) +Comment: For more information see http://www.suse.de/security + +mQENAzbhLQQAAAEIAKAkXHe0lWRBXLpn38hMHy03F0I4Sszmoc8aaKJrhfhyMlOA +BqvklPLE2f9UrI4Xc860gH79ZREwAgPt0pi6+SleNFLNcNFAuuHMLQOOsaMFatbz +JR9i4m/lf6q929YROu5zB48rBAlcfTm+IBbijaEdnqpwGib45wE/Cfy6FAttBHQh +1Kp+r/jPbf1mYAvljUfHKuvbg8t2EIQz/5yGp+n5trn9pElfQO2cRBq8LFpf1l+U +P7EKjFmlOq+Gs/fF98/dP3DfniSd78LQPq5vp8RL8nr/o2i7jkAQ33m4f1wOBWd+ +cZovrKXYlXiR+Bf7m2hpZo+/sAzhd7LmAD0l09kABRG0JVN1U0UgU2VjdXJpdHkg +VGVhbSA8c2VjdXJpdHlAc3VzZS5kZT6JARUDBRA24S1H5Fiyh7HKPEUBAVcOB/9b +yHYji1/+4Xc2GhvXK0FSJN0MGgeXgW47yxDL7gmR4mNgjlIOUHZj0PEpVjWepOJ7 +tQS3L9oP6cpj1Fj/XxuLbkp5VCQ61hpt54coQAvYrnT9rtWEGN+xmwejT1WmYmDJ +xG+EGBXKr+XP69oIUl1E2JO3rXeklulgjqRKos4cdXKgyjWZ7CP9V9daRXDtje63 +Om8gwSdU/nCvhdRIWp/Vwbf7Ia8iZr9OJ5YuQl0DBG4qmGDDrvImgPAFkYFzwlqo +choXFQ9y0YVCV41DnR+GYhwl2qBd81T8aXhihEGPIgaw3g8gd8B5o6mPVgl+nJqI +BkEYGBusiag2pS6qwznZiQEVAwUQNuEtBHey5gA9JdPZAQFtOAf+KVh939b0J94u +v/kpg4xs1LthlhquhbHcKNoVTNspugiC3qMPyvSX4XcBr2PC0cVkS4Z9PY9iCfT+ +x9WM96g39dAF+le2CCx7XISk9XXJ4ApEy5g4AuK7NYgAJd39PPbERgWnxjxir9g0 +Ix30dS30bW39D+3NPU5Ho9TD/B7UDFvYT5AWHl3MGwo3a1RhTs6sfgL7yQ3U+mvq +MkTExZb5mfN1FeaYKMopoI4VpzNVeGxQWIz67VjJHVyUlF20ekOz4kWVgsxkc8G2 +saqZd6yv2EwqYTi8BDAduweP33KrQc4KDDommQNDOXxaKOeCoESIdM4p7Esdjq1o +L0oixF12CohGBBARAgAGBQI7HmHDAAoJEJ5A4xAACqukTlQAoI4QzP9yjPohY7OU +F7J3eKBTzp25AJ42BmtSd3pvm5ldmognWF3Trhp+GYkAlQMFEDe3O8IWkDf+zvyS +FQEBAfkD/3GG5UgJj18UhYmh1gfjIlDcPAeqMwSytEHDENmHC+vlZQ/p0mT9tPiW +tp34io54mwr+bLPN8l6B5GJNkbGvH6M+mO7R8Lj4nHL6pyAv3PQr83WyLHcaX7It +Klj371/4yzKV6qpz43SGRK4MacLo2rNZ/dNej7lwPCtzCcFYwqkiiEYEEBECAAYF +AjoaQqQACgkQx1KqMrDf94ArewCfWnTUDG5gNYkmHG4bYL8fQcizyA4An2eVo/n+ +3J2KRWSOhpAMsnMxtPbBmQGiBDnu9IERBACT8Y35+2vv4MGVKiLEMOl9GdST6MCk +YS3yEKeueNWc+z/0Kvff4JctBsgs47tjmiI9sl0eHjm3gTR8rItXMN6sJEUHWzDP ++Y0PFPboMvKx0FXl/A0dM+HFrruCgBlWt6FA+okRySQiliuI5phwqkXefl9AhkwR +8xocQSVCFxcwvwCglVcOQliHu8jwRQHxlRE0tkwQQI0D+wfQwKdvhDplxHJ5nf7U +8c/yE/vdvpN6lF0tmFrKXBUX+K7u4ifrZlQvj/81M4INjtXreqDiJtr99Rs6xa0S +cZqITuZC4CWxJa9GynBED3+D2t1V/f8l0smsuYoFOF7Ib49IkTdbtwAThlZp8bEh +ELBeGaPdNCcmfZ66rKUdG5sRA/9ovnc1krSQF2+sqB9/o7w5/q2qiyzwOSTnkjtB +UVKn4zLUOf6aeBAoV6NMCC3Kj9aZHfA+ND0ehPaVGJgjaVNFhPi4x0e7BULdvgOo +AqajLfvkURHAeSsxXIoEmyW/xC1sBbDkDUIBSx5oej73XCZgnj/inphRqGpsb+1n +KFvF+rQoU3VTRSBQYWNrYWdlIFNpZ25pbmcgS2V5IDxidWlsZEBzdXNlLmRlPohc +BBMRAgAcBQI57vSBBQkDwmcABAsKAwQDFQMCAxYCAQIXgAAKCRCoTtronIAKyl8s +AJ98BgD40zw0GHJHIf6dNfnwI2PAsgCgjH1+PnYEl7TFjtZsqhezX7vZvYCIRgQQ +EQIABgUCOnBeUgAKCRCeQOMQAAqrpNzOAKCL512FZvv4VZx94TpbA9lxyoAejACe +OO1HIbActAevk5MUBhNeLZa/qM2JARUDBRA6cGBvd7LmAD0l09kBATWnB/9An5vf +iUUE1VQnt+T/EYklES3tXXaJJp9pHMa4fzFa8jPVtv5UBHGee3XoUNDVwM2OgSEI +SZxbzdXGnqIlcT08TzBUD9i579uifklLsnr35SJDZ6ram51/CWOnnaVhUzneOA9g +TPSr+/fT3WeVnwJiQCQ30kNLWVXWATMnsnT486eAOlT6UNBPYQLpUprF5Yryk23p +QUPAgJENDEqeU6iIO9Ot1ZPtB0lniw+/xCi13D360o1tZDYOp0hHHJN3D3EN8C1y +PqZd5CvvznYvB6bWBIpWcRgdn2DUVMmpU661jwqGlRz1F84JG/xe4jGuzgpJt9IX +SzyohEJB6XG5+D0BiF0EExECAB0FAjxqqTQFCQoAgrMFCwcKAwQDFQMCAxYCAQIX +gAAKCRCoTtronIAKyp1fAJ9dR7saz2KPNwD3U+fy/0BDKXrYGACfbJ8fQcJqCBQx +eHvt9yMPDVq0B0W5Ag0EOe70khAIAISR0E3ozF/la+oNaRwxHLrCet30NgnxRROY +hPaJB/Tu1FQokn2/Qld/HZnh3TwhBIw1FqrhWBJ7491iAjLR9uPbdWJrn+A7t8kS +kPaF3Z/6kyc5a8fas44ht5h+6HMBzoFCMAq2aBHQRFRNp9Mz1ZvoXXcI1lk1l8Oq +cUM/ovXbDfPcXsUVeTPTtGzcAi2jVl9hl3iwJKkyv/RLmcusdsi8YunbvWGFAF5G +aagYQo7YlF6UaBQnYJTM523AMgpPQtsKm9o/w9WdgXkgWhgkhZEeqUS3m5xNey1n +Lu9iMvq9M/iXnGz4sg6Q2Y+GqZ+yAvNWjRRou3zSE7Bzg28MI4sAAwYH/2D71Xc5 +HPDgu87WnBFgmp8MpSr8QnSs0wwPg3xEullGEocolSb2c0ctuSyeVnCttJMzkukL +9TqyF4s/6XRstWirSWawJxRLKH6Zjo/FaKsshYKf8gBkAaddvpl3pO0gmUYbqmpQ +3xDEYlhCeieXS5MkockQ1sj2xYdB1xO0ExzfiCiscUKjUFy+mdzUsUutafuZ+gbH +og1CN/ccZCkxcBa5IFCHORrNjq9pYWlrxsEn6ApsG7JJbM2besW1PkdEoxak74z1 +senh36m5jQvVjA3U4xq1wwylxadmmJaJHzeiLfb7G1ZRjZTsB7fyYxqDzMVul6o9 +BSwO/1XsIAnV1uuITAQYEQIADAUCOe70kgUJA8JnAAAKCRCoTtronIAKyksiAJsF +B3/77SkH3JlYOGrEe1Ol0JdGwACeKTttgeVPFB+iGJdiwQlxasOfuXyITAQYEQIA +DAUCPGqpWQUJCgCCxwAKCRCoTtronIAKyofBAKCSZM2UFyta/fe9WgITK9I5hbxx +tQCfX+0ar2CZmSknn3coSPihn1+OBNw= +=r69E +-----END PGP PUBLIC KEY BLOCK----- +</pre> + <br /><br /> + + + </div> + <div class="content_right"> + <div id="rac_preview" class="rac_button_embedded"> + <p class="button button_chat"><a href="#"><span>Chat Now</span></a></p> +</div> + +<div id="requestcall"> + + <script type="text/javascript" src="http://www.novell.com/company/sales_call_request_translated_javascript.js"></script> + <script type="text/javascript" src="http://www.novell.com/inc/util/secure/userInfo.php"></script> + <script type="text/javascript" src="http://www.novell.com/inc/util/pagequery.js"></script> + + + <p class="title">Request a Call</p> + + + <p class="phonecall">Call <script type="text/javascript">document.write(n_phone);</script> or complete the form below.</p> + <div id="form_wrap"> + <div id="form_content"> + <p id="required_note"><span class="req">*</span> Required Fields</p> + <form id="salescallrequest" method="post" action="http://www.novell.com/surveyutil/route_survey_data.jsp" onsubmit="return formCheck(this);"> + <fieldset> + <input type="hidden" name="survey-id" value="400"> + <input type="hidden" name="charset" value=""> + <input type="hidden" name="email_to" value="crc@novell.com"> + <input type="hidden" name="email_cc" value=""> + <input type="hidden" name="email_bcc" value="jwhitloc@novell.com"> + <input type="hidden" name="email_from" value="sales_call_request@suse.com"> + <input type="hidden" name="email_subject" value="SUSE.com Web Lead - Call Immediately"> + <input type="hidden" name="fromUrl" id="fromUrl" value=""> + <input type="hidden" name="send_html" value="true"> + <input type="hidden" name="email_template" value="/company/sales_call_request_template_new.txt"> + <input type="hidden" name="thankyou_page" value="http://www.suse.com/company/thankyou.html"> + <input type="hidden" name="request_from" value="Request a call"> + <input type="hidden" name="novell_magic_field" value=""> + <input type="hidden" name="question_6241" value=""> + <input type="hidden" name="question_6242" value=""> + <input type="hidden" name="question_7040" value=""> + <input type="hidden" name="question_6425" value=""> + <input type="hidden" name="question_6243" value=""> + <input type="hidden" name="question_7478" value=""> + <input type="hidden" name="question_7519" value=""> + <input type="hidden" name="question_7648" value=""> + <input type="hidden" name="question_7649" value=""> + + <div id="requestcall_fname" class="half"><label for="question_6173">First Name <span class="req">*</span></label> <input type="text" id="question_6173" name="question_6173"></div> + <div id="requestcall_lname" class="half last"><label for="question_6174">Last Name <span class="req">*</span></label> <input type="text" id="question_6174" name="question_6174"></div> + + <div id="requestcall_company" class="half"><label for="question_6175">Company <span class="req">*</span></label> <input type="text" id="question_6175" name="question_6175"></div> + <div id="requestcall_phone" class="half last"><label for="question_6177">Phone <span class="req">*</span></label> <input type="text" id="question_6177" name="question_6177" onchange="setPhoneChanged();" onfocus="clearPrefill(this)"></div> + <div id="requestcall_address" style="display:none;"><label for="question_6179">Street Address <span class="req">*</span></label> <input type="text" id="question_6179" name="question_6179"></div> + <div id="requestcall_state" style="display:none;"><label for="question_6182">State/Province <span class="req">*</span></label> <input type="text" id="question_6182" name="question_6182"></div> + + <div id="requestcall_postal" style="display:none;"><label for="question_6183">Postal Code <span class="req">*</span></label> <input type="text" id="question_6183" name="question_6183"></div> + <div id="requestcall_city" class="half"><label for="question_6181">City <span class="req">*</span></label> <input type="text" id="question_6181" name="question_6181"></div> + <div id="requestcall_country" class="half last"><label for="question_6178">Country <span class="req">*</span></label> + <select name="question_6178" id="question_6178" onchange="setPhonePrefill(this.value);"> + <option value=""> </option> + + <option value=""></option> +<option value="United States">United States</option> +<option value="Germany">Germany</option> +<option value="India">India</option> +<option value="">-----</option> +<option value="Afghanistan">Afghanistan</option> +<option value="Albania">Albania</option> +<option value="Algeria">Algeria</option> +<option value="American Samoa">American Samoa</option> +<option value="Andorra">Andorra</option> +<option value="Angola">Angola</option> +<option value="Anguilla">Anguilla</option> +<option value="Antarctica">Antarctica</option> +<option value="Antigua and Barbuda">Antigua and Barbuda</option> +<option value="Argentina">Argentina</option> +<option value="Armenia">Armenia</option> +<option value="Aruba">Aruba</option> +<option value="Australia">Australia</option> +<option value="Austria">Austria</option> +<option value="Azerbaijan">Azerbaijan</option> +<option value="Bahamas">Bahamas</option> +<option value="Bahrain">Bahrain</option> +<option value="Bangladesh">Bangladesh</option> +<option value="Barbados">Barbados</option> +<option value="Belarus">Belarus</option> +<option value="Belgium">Belgium</option> +<option value="Belize">Belize</option> +<option value="Benin">Benin</option> +<option value="Bermuda">Bermuda</option> +<option value="Bhutan">Bhutan</option> +<option value="Bolivia">Bolivia</option> +<option value="Bosnia and Herzegovina">Bosnia and Herzegovina</option> +<option value="Botswana">Botswana</option> +<option value="Bouvet Island">Bouvet Island</option> +<option value="Brazil">Brazil</option> +<option value="British Indian Ocean Territory">British Indian Ocean Territory</option> +<option value="Brunei Darussalam">Brunei Darussalam</option> +<option value="Bulgaria">Bulgaria</option> +<option value="Burkina Faso">Burkina Faso</option> +<option value="Burundi">Burundi</option> +<option value="Cambodia">Cambodia</option> +<option value="Cameroon">Cameroon</option> +<option value="Canada">Canada</option> +<option value="Cape Verde">Cape Verde</option> +<option value="Cayman Islands">Cayman Islands</option> +<option value="Central African Republic">Central African Republic</option> +<option value="Chad">Chad</option> +<option value="Chile">Chile</option> +<option value="China">China</option> +<option value="Christmas Island">Christmas Island</option> +<option value="Cocos (Keeling) Islands">Cocos (Keeling) Islands</option> +<option value="Colombia">Colombia</option> +<option value="Comoros">Comoros</option> +<option value="Congo">Congo</option> +<option value="Cook Islands">Cook Islands</option> +<option value="Costa Rica">Costa Rica</option> +<option value="Cote d'Ivoire">Cote d'Ivoire</option> +<option value="Croatia">Croatia</option> +<option value="Cyprus">Cyprus</option> +<option value="Czech Republic">Czech Republic</option> +<option value="Denmark">Denmark</option> +<option value="Djibouti">Djibouti</option> +<option value="Dominica">Dominica</option> +<option value="Dominican Republic">Dominican Republic</option> +<option value="Ecuador">Ecuador</option> +<option value="Egypt">Egypt</option> +<option value="El Salvador">El Salvador</option> +<option value="Equatorial Guinea">Equatorial Guinea</option> +<option value="Eritrea">Eritrea</option> +<option value="Estonia">Estonia</option> +<option value="Ethiopia">Ethiopia</option> +<option value="Falkland Islands (Malvinas)">Falkland Islands (Malvinas)</option> +<option value="Faroe Islands">Faroe Islands</option> +<option value="Fiji Islands">Fiji Islands</option> +<option value="Finland">Finland</option> +<option value="France">France</option> +<option value="French Guiana">French Guiana</option> +<option value="French Polynesia">French Polynesia</option> +<option value="French Southern Territories">French Southern Territories</option> +<option value="Gabon">Gabon</option> +<option value="Gambia">Gambia</option> +<option value="Georgia">Georgia</option> +<option value="Ghana">Ghana</option> +<option value="Gibraltar">Gibraltar</option> +<option value="Greece">Greece</option> +<option value="Greenland">Greenland</option> +<option value="Grenada">Grenada</option> +<option value="Guadeloupe">Guadeloupe</option> +<option value="Guam">Guam</option> +<option value="Guatemala">Guatemala</option> +<option value="Guinea">Guinea</option> +<option value="Guinea-Bissau">Guinea-Bissau</option> +<option value="Guyana">Guyana</option> +<option value="Haiti">Haiti</option> +<option value="Heard Island and McDonald Islands">Heard Island and McDonald Islands</option> +<option value="Honduras">Honduras</option> +<option value="Hong Kong">Hong Kong</option> +<option value="Hungary">Hungary</option> +<option value="Iceland">Iceland</option> +<option value="Indonesia">Indonesia</option> +<option value="Iraq">Iraq</option> +<option value="Ireland">Ireland</option> +<option value="Israel">Israel</option> +<option value="Italy">Italy</option> +<option value="Jamaica">Jamaica</option> +<option value="Japan">Japan</option> +<option value="Jordan">Jordan</option> +<option value="Kazakhstan">Kazakhstan</option> +<option value="Kenya">Kenya</option> +<option value="Kiribati">Kiribati</option> +<option value="Korea">Korea, Republic of</option> +<option value="Kuwait">Kuwait</option> +<option value="Kyrgyzstan">Kyrgyzstan</option> +<option value="Lao People's Democratic Republic">Lao People's Democratic Republic</option> +<option value="Latvia">Latvia</option> +<option value="Lebanon">Lebanon</option> +<option value="Lesotho">Lesotho</option> +<option value="Liberia">Liberia</option> +<option value="Libyan Arab Jamahiriya">Libyan Arab Jamahiriya</option> +<option value="Liechtenstein">Liechtenstein</option> +<option value="Lithuania">Lithuania</option> +<option value="Luxembourg">Luxembourg</option> +<option value="Macao">Macao</option> +<option value="Macedonia">Macedonia</option> +<option value="Madagascar">Madagascar</option> +<option value="Malawi">Malawi</option> +<option value="Malaysia">Malaysia</option> +<option value="Maldives">Maldives</option> +<option value="Mali">Mali</option> +<option value="Malta">Malta</option> +<option value="Marshall Islands">Marshall Islands</option> +<option value="Martinique">Martinique</option> +<option value="Mauritania">Mauritania</option> +<option value="Mauritius">Mauritius</option> +<option value="Mayotte">Mayotte</option> +<option value="Mexico">Mexico</option> +<option value="Micronesia">Micronesia, Federated States of</option> +<option value="Moldova, Republic of">Moldova, Republic of</option> +<option value="Monaco">Monaco</option> +<option value="Mongolia">Mongolia</option> +<option value="Montserrat">Montserrat</option> +<option value="Morocco">Morocco</option> +<option value="Mozambique">Mozambique</option> +<option value="Myanmar">Myanmar</option> +<option value="Namibia">Namibia</option> +<option value="Nauru">Nauru</option> +<option value="Nepal">Nepal</option> +<option value="Netherlands">Netherlands</option> +<option value="Netherlands Antilles">Netherlands Antilles</option> +<option value="New Caledonia">New Caledonia</option> +<option value="New Zealand">New Zealand</option> +<option value="Nicaragua">Nicaragua</option> +<option value="Niger">Niger</option> +<option value="Nigeria">Nigeria</option> +<option value="Niue">Niue</option> +<option value="Norfolk Island">Norfolk Island</option> +<option value="Northern Mariana Islands">Northern Mariana Islands</option> +<option value="Norway">Norway</option> +<option value="Oman">Oman</option> +<option value="Pakistan">Pakistan</option> +<option value="Palau">Palau</option> +<option value="Palestinian Territory">Palestinian Territory, Occupied</option> +<option value="Panama">Panama</option> +<option value="Papua New Guinea">Papua New Guinea</option> +<option value="Paraguay">Paraguay</option> +<option value="Peru">Peru</option> +<option value="Philippines">Philippines</option> +<option value="Pitcairn">Pitcairn</option> +<option value="Poland">Poland</option> +<option value="Portugal">Portugal</option> +<option value="Puerto Rico">Puerto Rico</option> +<option value="Qatar">Qatar</option> +<option value="Reunion">Reunion</option> +<option value="Romania">Romania</option> +<option value="Russia">Russia</option> +<option value="Rwanda">Rwanda</option> +<option value="Saint Helena">Saint Helena</option> +<option value="Saint Kitts and Nevis">Saint Kitts and Nevis</option> +<option value="Saint Lucia">Saint Lucia</option> +<option value="Saint Pierre and Miquelon">Saint Pierre and Miquelon</option> +<option value="Saint Vincent and the Grenadines">Saint Vincent and the Grenadines</option> +<option value="Samoa">Samoa</option> +<option value="San Marino">San Marino</option> +<option value="Sao Tome and Principe">Sao Tome and Principe</option> +<option value="Saudi Arabia">Saudi Arabia</option> +<option value="Senegal">Senegal</option> +<option value="Serbia and Montenegro">Serbia and Montenegro</option> +<option value="Seychelles">Seychelles</option> +<option value="Sierra Leone">Sierra Leone</option> +<option value="Singapore">Singapore</option> +<option value="Slovakia">Slovakia</option> +<option value="Slovenia">Slovenia</option> +<option value="Solomon Islands">Solomon Islands</option> +<option value="Somalia">Somalia</option> +<option value="South Africa">South Africa</option> +<option value="South Georgia and the South Sandwich Islands">South Georgia and the South Sandwich Islands</option> +<option value="Spain">Spain</option> +<option value="Sri Lanka">Sri Lanka</option> +<option value="Suriname">Suriname</option> +<option value="Svalbard and Jan Mayen">Svalbard and Jan Mayen</option> +<option value="Swaziland">Swaziland</option> +<option value="Sweden">Sweden</option> +<option value="Switzerland">Switzerland</option> +<option value="Taiwan">Taiwan, Republic of China</option> +<option value="Tajikistan">Tajikistan</option> +<option value="Tanzania">Tanzania</option> +<option value="Thailand">Thailand</option> +<option value="Timor-Leste">Timor-Leste</option> +<option value="Togo">Togo</option> +<option value="Tokelau">Tokelau</option> +<option value="Tonga">Tonga</option> +<option value="Trinidad and Tobago">Trinidad and Tobago</option> +<option value="Tunisia">Tunisia</option> +<option value="Turkey">Turkey</option> +<option value="Turkmenistan">Turkmenistan</option> +<option value="Turks and Caicos Islands">Turks and Caicos Islands</option> +<option value="Tuvalu">Tuvalu</option> +<option value="Uganda">Uganda</option> +<option value="Ukraine">Ukraine</option> +<option value="United Arab Emirates">United Arab Emirates</option> +<option value="United Kingdom">United Kingdom</option> +<option value="United States Minor Outlying Islands">United States Minor Outlying Islands</option> +<option value="Uruguay">Uruguay</option> +<option value="Uzbekistan">Uzbekistan</option> +<option value="Vanuatu">Vanuatu</option> +<option value="Vatican City State">Vatican City State</option> +<option value="Venezuela">Venezuela</option> +<option value="Vietnam">Vietnam</option> +<option value="Virgin Islands-British">Virgin Islands, British</option> +<option value="Virgin Islands-U.S.">Virgin Islands, U.S.</option> +<option value="Wallis and Futuna">Wallis and Futuna</option> +<option value="Western Sahara">Western Sahara</option> +<option value="Yemen">Yemen</option> +<option value="Zambia">Zambia</option> +<option value="Zimbabwe">Zimbabwe</option> + + </select> + </div> + <div id="requestcall_email"><label for="question_6176">Email Address <span class="req">*</span></label> <input type="text" id="question_6176" name="question_6176"></div> + <div id="requestcall_comments"><label for="question_6184">Comments</label> <textarea name="question_6184" id="question_6184" class="expanding" rows="2" cols="15"></textarea></div> + + <p id="disclaimer">Read our <a href="/company/policies/privacy/">Privacy Policy</a>.</p> + + <p class="form_submit_hide"><input type="submit" value="Submit"></p> + </fieldset> + </form> + </div> + <div class="form_submit"> + <p><a href="#">Request a Call ›</a></p> + </div> + </div> +</div> + </div> + <div class="clr"></div> + </div> + </div> + </div> + </div> + <footer> + + <div class="footer_global"> + <div class="wrap"> + <p>© 2012 SUSE</p> + <ul> + <li><a href="/company/careers/" target="_top">Careers</a></li> + <li><a href="/company/legal/" target="_top">Legal</a></li> + <li><a href="#" class="feedback">Feedback</a></li> + <li><a href="/company/" target="_top">About</a></li> + <li><a href="/ContactsOffices/contacts_offices.jsp" target="_top">Contact Us</a></li> + </ul> + <p id="suse_phone"><a href="#" class="rac"><script type="text/javascript">if(typeof n_phone != "undefined"){ document.write(n_phone); }</script></a></p> + <div class="clr"></div> + </div> + </div> + + + + + + + + </footer> +</div> <!--! end of #container --> +<!-- Non-page-dependent JS at the bottom for fast page loading --> + +<!--[if lt IE 7 ]> + <script src="/common/inc/js/dd_belatedpng.js"></script> + <script>DD_belatedPNG.fix("img, .png_bg"); // Fix any <img> or .png_bg bg-images. Also, please read goo.gl/mZiyb </script> +<![endif]--> + +<script type="text/javascript"> + var ga_code = (window.location.href.indexOf("wwwstage") > -1 || window.location.href.indexOf("wwwtest") > -1) ? "UA-23738999-2" : "UA-23738999-1"; //-2 is stage, -1 is prod + var gaevent_code = (window.location.href.indexOf("wwwstage") > -1 || window.location.href.indexOf("wwwtest") > -1) ? "UA-23741840-2" : "UA-23741840-1"; //-2 is stage, -1 is prod + var trackPageViewOnLoad = (typeof trackPageViewOnLoad != "undefined" && trackPageViewOnLoad === false) ? false : true; + var _gaq=[ + ["_setAccount",ga_code], + ["_setDomainName",".suse.com"], + ["event._setAccount",gaevent_code], + ["event._setDomainName",".suse.com"], + ]; + if(trackPageViewOnLoad) { + if(typeof is404Page != "undefined" && is404Page === true) { + _gaq.push(["_trackPageview", "/404.html?page=" + document.location.pathname + document.location.search + "&from=" + document.referrer]); + } + else { + _gaq.push(["_trackPageview"]); + } + _gaq.push(["event._trackPageview"]); + } + (function(d,t){var g=d.createElement(t),s=d.getElementsByTagName(t)[0];g.async=1; + g.src=("https:"==location.protocol?"//ssl":"//www")+".google-analytics.com/ga.js"; + s.parentNode.insertBefore(g,s)}(document,"script")); +</script> +<script> + //begin suse_gaevent checking + var params = document.params; + if(!params) { + document.params = (location.search.substring(1)).split("&"); + params = document.params; + } + if(typeof params != "undefined" && params != "") { + for(var i = 0; i < params.length; i++) { + var param = params[i].split("="); + if(param[0] == "suse_gaevent") { + _gaq.push(['event._trackEvent', 'Ad Tracking', 'clicks', param[1]]); //log the click + } + } + } + //end suse_gaevent checking +</script> +<script src="/common/inc/js/plugins.js?v=1"></script> +<script src="/common/inc/js/main.js?v=11"></script> +<script src="/common/inc/js/blindformsubmit.js?v=1"></script> +<script src="/common/inc/js/plugins/scroll/jScrollPane.js?v=1"></script> +<script src="/common/inc/js/plugins/scroll/jquery.mousewheel.js?v=1"></script> +<script src="/common/inc/js/rac.js"></script> + +<script type="text/javascript" src="http://www.novell.com/common/inc/elqNow/elqCfg.js"></script> +<script type="text/javascript" src="http://www.novell.com/common/inc/elqNow/elqImg.js"></script> +<script type="text/javascript" src="http://www.novell.com/common/inc/elqNow/elqCPers.js"></script> + +<!--[if !IE]>--> +<script> + // dom fixup for gecko pre 1.9b5; see http://blog.whatwg.org/supporting-new-elements-in-firefox-2 + function fixForFF(){ + var n = document.getElementsByTagName('header')[0]; + if (n.childNodes.length <= 1) { // the element was closed early + n.appendChild(n.nextSibling); + var f = document.getElementsByTagName('footer')[0]; + f.appendChild(f.nextSibling); + + if($("#product").hasClass("product_index") || $("#newsticker").length){ //product or home pages have two child divs + f.appendChild(f.nextSibling); + f.appendChild(f.nextSibling); + } + } + } + if($("header").length){ + fixForFF(); + } + //subdomains which pull in the header/footer via JS won't render in time, so they'll call the funtion directly. +</script> +<!--<![endif]--> +</body> +</html>
\ No newline at end of file diff --git a/tests2/files/main.css b/tests2/files/main.css new file mode 100644 index 00000000..0e62d7da --- /dev/null +++ b/tests2/files/main.css @@ -0,0 +1,1744 @@ +/** + * html5doctor.com Reset Stylesheet (Eric Meyer's Reset Reloaded + HTML5 baseline) + * v1.6.1 2010-09-17 | Authors: Eric Meyer & Richard Clark + * html5doctor.com/html-5-reset-stylesheet/ + */ + +body{ font-family: Helvetica, Arial, sans-serif; } + +html, body, div, span, object, iframe, +h1, h2, h3, h4, h5, h6, p, blockquote, pre, +abbr, address, cite, code, del, dfn, em, img, ins, kbd, q, samp, +small, strong, sub, sup, var, b, i, dl, dt, dd, ol, ul, li, +fieldset, form, label, legend, +table, caption, tbody, tfoot, thead, tr, th, td, +article, aside, canvas, details, figcaption, figure, +footer, header, hgroup, menu, nav, section, summary, +time, mark, audio, video { + margin: 0; + padding: 0; + border: 0; + font-size: 100%; +/* font: inherit;*/ +/* font-family:Omnes_Regular;*/ +/* font-family: Helvetica, Arial, sans-serif;*/ + vertical-align: baseline; +} + +article, aside, details, figcaption, figure, +footer, header, hgroup, menu, nav, section { + display: block; +} + +blockquote, q { quotes: none; } +blockquote:before, blockquote:after, +q:before, q:after { content: ""; content: none; } +ins { background-color: #ff9; color: #000; text-decoration: none; } +mark { background-color: #ff9; color: #000; font-style: italic; font-weight: bold; } +del { text-decoration: line-through; } +abbr[title], dfn[title] { border-bottom: 1px dotted; cursor: help; } +table { border-collapse: collapse; border-spacing: 0; } +hr { display: block; height: 1px; border: 0; border-top: 1px solid #ccc; margin: 1em 0; padding: 0; } +input, select { vertical-align: middle; } +a{ outline:none; } + +/** + * Font normalization inspired by YUI Library's fonts.css: developer.yahoo.com/yui/ + */ + +body { font:13px/1.231 Helvetica, Arial, sans-serif; *font-size:small; } /* Hack retained to preserve specificity */ +select, input, textarea, button { font:99% sans-serif; } + +/* Normalize monospace sizing: + en.wikipedia.org/wiki/MediaWiki_talk:Common.css/Archive_11#Teletype_style_fix_for_Chrome */ +pre, code, kbd, samp { font-family: monospace, sans-serif; } + +/** + * Minimal base styles. + */ + +/* Always force a scrollbar in non-IE */ +html { overflow-y: scroll; } + +/* Accessible focus treatment: people.opera.com/patrickl/experiments/keyboard/test */ +a:hover, a:active { outline: none; } + +ul, ol { margin-left: 1.2em; } +ol { list-style-type: decimal; } + +/* Remove margins for navigation lists */ +nav ul, nav li { margin: 0; list-style:none; list-style-image: none; } + +small { font-size: 85%; } +strong, th { font-weight: bold; /*font-family:Omnes_Medium;*/ } + +td { vertical-align: top; } + +/* Set sub, sup without affecting line-height: gist.github.com/413930 */ +sub, sup { font-size: 75%; line-height: 0; position: relative; } +sub.article_promoted_text{ line-height:14px; position:static; } +sup { top: -0.5em; } +sub { bottom: -0.25em; } + +pre { + /* www.pathf.com/blogs/2008/05/formatting-quoted-code-in-blog-posts-css21-white-space-pre-wrap/ */ + white-space: pre; white-space: pre-wrap; word-wrap: break-word; + padding: 15px; +} + +h1{ font-size:30px; line-height:30px; font-weight:400; color:#439539; } + +textarea { overflow: auto; } /* www.sitepoint.com/blogs/2010/08/20/ie-remove-textarea-scrollbars/ */ + +.ie6 legend, .ie7 legend { margin-left: -7px; } + +/* Align checkboxes, radios, text inputs with their label by: Thierry Koblentz tjkdesign.com/ez-css/css/base.css */ +input[type="radio"] { vertical-align: text-bottom; } +input[type="checkbox"] { vertical-align: bottom; } +.ie7 input[type="checkbox"] { vertical-align: baseline; } +.ie6 input { vertical-align: text-bottom; } + +/* Hand cursor on clickable input elements */ +label, input[type="button"], input[type="submit"], input[type="image"], button { cursor: pointer; } + +/* Webkit browsers add a 2px margin outside the chrome of form elements */ +button, input, select, textarea { margin: 0; } + +/* Colors for form validity */ +input:valid, textarea:valid { } +input:invalid, textarea:invalid { + border-radius: 1px; -moz-box-shadow: 0px 0px 5px red; -webkit-box-shadow: 0px 0px 5px red; box-shadow: 0px 0px 5px red; +} +.no-boxshadow input:invalid, .no-boxshadow textarea:invalid { background-color: #f0dddd; } + +/* These selection declarations have to be separate + No text-shadow: twitter.com/miketaylr/status/12228805301 + Also: hot pink! */ +::-moz-selection{ background: #439339; color:#fff; text-shadow: none; } +::selection { background:#439339; color:#fff; text-shadow: none; } + +/* j.mp/webkit-tap-highlight-color */ +a:link { -webkit-tap-highlight-color: #FF5E99; } + +/* Make buttons play nice in IE: + www.viget.com/inspire/styling-the-button-element-in-internet-explorer/ */ +button { width: auto; overflow: visible; } + +/* Bicubic resizing for non-native sized IMG: + code.flickr.com/blog/2008/11/12/on-ui-quality-the-little-things-client-side-image-resizing/ */ +.ie7 img { -ms-interpolation-mode: bicubic; } + +/** + * You might tweak these.. + */ + +body, select, input, textarea { + /* #444 looks better than black: twitter.com/H_FJ/statuses/11800719859 */ + color: #444; + /* Set your base font here, to apply evenly */ + /* font-family: Georgia, serif; */ +} + +/** + * Primary styles + */ + +/* Basic formatting, structure +----------------------------------- */ +body{ font-family:Arial, Helvetica, sans-serif; } +.wrap{ width:978px; margin:0 auto; padding:0 20px; } + +/* The Magnificent Clearfix: Updated to prevent margin-collapsing on child elements. j.mp/bestclearfix */ +.clr:before, .clr:after { content: "\0020"; display: block; height: 0; overflow: hidden; } +.clr:after { clear: both; } +/* Fix clearfix: blueprintcss.lighthouseapp.com/projects/15318/tickets/5-extra-margin-padding-bottom-of-page */ +.clr { zoom: 1; } +.ie6 .clr, .ie7 .clr{ clear:both; height:1px; } /* This shouldn't be necessary but IE isn't playing nice with the .clr method used */ + +#content > .wrap{ padding-bottom:90px; } +.content_left{ float:left; width:705px; margin-right:50px; } +.content_right{ float:left; width:222px; } + +.longtail .content_left, .how_to_buy .content_left, .services_support .content_left, .technical_information .content_left{ width:723px; margin-right:32px; } +#product .col_small, #partner .col_small, #solution .col_small, #solution .col_small{ width:222px; margin-right:30px; float:left; position:relative; } +#product .col_large, #partner .col_large, #solution .col_large, #solution .col_large{ width:471px; float:left; position:relative; } +.content_left .col_half{ float:left; width:345px; } +.content_left .even{ margin-right:32px; } + +#content > .wrap > .col_half{ float:left; width:473px; overflow:hidden; } +#content > .wrap > .even{ margin-right:32px; } + +/* Header +----------------------------------- */ +header{ /*border-top:3px solid #333;*/ height:100px; } +header .wrap{ position:relative; z-index:1000; } +/*header .wrap p.portal{ position:absolute; top:0; right:0; background:#333 url(/common/img/portal_curve.png) top left no-repeat; margin:0; padding:0; font-size:11px; text-transform:uppercase; font-weight:300; } +header .wrap p.portal a{ color:#fff; text-decoration:none; padding:3px 25px 1px 48px; height:19px; display:block; } +header .wrap p.portal a strong{ color:#79C043; } +*/ +header ul#meta{ margin:0; padding:0; list-style-type:none; position:absolute; top:12px; right:160px; } +header ul#meta li{ float:left; padding:4px 15px; border-left:1px solid #f6f6f6; } +header ul#meta li:first-child{ border-left:none; } +header ul#meta li a{ color:#666; text-decoration:none; font-size:11px; } +header ul#meta li a:hover{ text-decoration:underline; } +header ul#meta li strong { font-size:11px; font-weight:normal; } +header ul#meta li#meta_countrylang a{ font-style:italic; } + +header #search{ width:138px; height:25px; background:url(/common/img/search.png) top left no-repeat; position:absolute; top:12px; right:20px; } +header #search form{ margin:0; padding:0; position:relative; display:block; } +header #search form label{ position:absolute; top:3px; left:3px; width:105px; height:19px; z-index:101; font:11px Helvetica, Arial, sans-serif; color:#666; padding:5px 0 0 5px; } +header #search form input#q{ margin:3px; border:none; border-color:transparent; width:105px; height:15px; padding:2px; /*position:relative;*/ z-index:100; } +header #search form input#q_submit{ display:block; text-indent:-9999px; width:23px; height:23px; position:absolute; top:0; right:0; background:none; border:none; } +header #search.focus{ box-shadow: 0 0 10px #439539; -webkit-box-shadow: 0 0 10px #439539; -moz-box-shadow: 0 0 10px #439539; } +header #search.focus input:focus{ outline-width:0; outline:none; } + +header #logo{ width:107px; height:50px; background:url(/common/img/logo.png) bottom left no-repeat; float:left; padding-top:32px; } +header #logo a{ display:block; text-indent:-9999px; width:107px; height:50px; } + +header ul#nav{ margin:0; padding:0; list-style-type:none; float:right; padding-top:55px; } +header ul#nav li{ float:left; font-size:11px; text-transform:uppercase; width:139px; text-align:center; font-weight:300; font-family:Helvetica, Arial, sans-serif; letter-spacing:0.5px; padding:15px 0; position:relative; z-index:999; } +header ul#nav li.active{ background:#4B9037; } +header ul#nav li.active_nosub{ background:#eee; padding-bottom:14px; } +header ul#nav li div.nav_sub{ display:none; /*background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0, rgba(255,255,255,0)), color-stop(1, rgba(255,255,255,.8))); background-image: -moz-linear-gradient(top, rgba(255,255,255,0), rgba(255,255,255,.8));*/ } +header ul#nav li.active div.nav_sub{ display:block; } +.ie6 ul#nav li.active div.nav_sub, .ie7 ul#nav li.active div.nav_sub{ background:url(/common/img/transparent_pixel.png) top left no-repeat; } /*http://www.webtechwise.com/fix-ie7-submenu-hover-problem/*/ + +header ul#nav li#nav_solutions{ width:125px; } +header ul#nav li#nav_products{ width:185px; } +header ul#nav li#nav_support{ width:105px; } +header ul#nav li#nav_partners{ width:115px; } +header ul#nav li#nav_community{ width:115px; } +header ul#nav li#nav_dl{ width:155px; } +header ul#nav li#nav_shop{ width:65px; padding-right:0; } +header ul#nav li a{ background:url(/common/img/bullets/nav.png) bottom right no-repeat; padding:5px 7px 3px; color:#666; text-decoration:none; line-height:16px; } +header ul#nav li.active a{ color:#fff; } +/*header ul#nav li a:hover{ background:#eee; color:#439539; }*/ +header ul#nav li.highlight.last-child{ text-align:right;} +header ul#nav li.highlight a{ color:#439539; } + +header ul#nav .nav_sub{ width:954px; padding:0 12px 12px 12px; z-index:998; position:absolute; top:46px; } +.ie7 header ul#nav .nav_sub{ top:44px; } +header ul#nav li#nav_solutions .nav_sub{ left:-125px; } +header ul#nav li#nav_products .nav_sub{ left:-238px; } +header ul#nav li#nav_support .nav_sub{ left:-423px; } +header ul#nav li#nav_partners .nav_sub{ left:-528px; } +header ul#nav li#nav_community .nav_sub{ left:-77px; } +header ul#nav .nav_sub_contents{ padding:32px; background:#4B9037; text-align:left; text-transform:none; letter-spacing:0; z-index:997; } +.ie6 header ul#nav .nav_sub_contents, .ie7 header ul#nav .nav_sub_contents{ padding-bottom:0; } +header ul#nav .nav_subheading{ color:#88d847; font-size:15px; font-weight:300; padding-bottom:12px; text-transform:none; } +header ul#nav .nav_subheading a{ color:#88d847 !important; background:none; padding:0; text-transform:none; } +header ul#nav .nav_subheading a:hover{ text-decoration:underline; } +header ul#nav .col_two{ width:185px; float:left; margin-right:32px; } +header ul#nav .col_three{ width:274px; float:left; margin-right:32px; } +header ul#nav .col_four{ width:198px; float:left; margin-right:32px; } +header ul#nav .col_five{ width:152px; float:left; margin-right:32px; } +header ul#nav .last{ margin-right:0; } +header ul#nav .col ul, header ul#nav .col ul li{ margin:0; padding:0; list-style-type:none; } +header ul#nav .col ul li{ font-size:11px; line-height:13px; padding:3px 0; border-bottom:1px solid #7ac142; text-align:left; text-transform:none; width:100%; } +header ul#nav .col ul li:first-child{ border-top:1px solid #7ac142; } +header ul#nav .col ul li a{ text-decoration:none; color:#fff; background:none; padding:0; line-height:13px; } +header ul#nav .col ul li a:hover{ color:#DFFFBF; } + +header ul#nav #nav_community .nav_sub{ width:254px; left:590px; } +header ul#nav #nav_solutions .nav_sub{ width:486px; } + +header #lang_select{ background:#202020; width:275px; overflow:hidden; position:absolute; top:15px; right:9999px; z-index:1000; padding-bottom:30px; height:200px; } +header #lang_select_top{ position:relative; height:25px; width:100%; } +header #lang_select_close{ position:absolute; top:12px; right:12px; margin:0; padding:0; width:16px; height:16px; } +header #lang_select_close a{ display:block; width:16px; height:16px; background:url(/common/img/hdr/lang_select_close.png) top left no-repeat; text-indent:-9999px; } +header #lang_select_close a:hover{ background-position:0 -16px; } +header #lang_select_content{ padding:0px 10px 0px 15px; } +header #lang_select_heading{ font-weight:bold; position:absolute; top:12px; left:60px; font-size:13px; color:#fff; margin:0; } +header #lang_select #countries_hdr, header #lang_select #countries{ display:none; } +header #lang_select .scroll-pane{ height:395px; } +header #lang_select hr{ background:#474747; color:#474747; height:1px; border:none; font-size:1px; line-height:1px; width:100%; overflow:hidden; margin:8px 0; } +header #lang_select hr.dark{ background:#292929; color:#292929; } +header #lang_select p{ margin:0; padding:0; } +header #lang_select p strong{ color:#76AD2D; } +header #lang_select p.section{ font-size:11px; color:#999; padding-bottom:7px; } +header #lang_select p#lang_selection{ font-weight:bold; color:#fff; } +header #lang_select p#lang_selection span{ color:#999; font-weight:normal; font-size:11px; } +header #lang_select p#lang_selection a{ color:#999; text-decoration:none; } +header #lang_select ul, header #lang_select ul li{ margin:0; padding:0; list-style-type:none; } +header #lang_select ul li{ font-size:13px; margin:0; padding:0; } +header #lang_select ul li a{ color:#ccc; text-decoration:none; display:block; padding:1px 0 1px 15px; margin:0; min-height:12px; height:auto !important; height:12px; } +header #lang_select ul li a:hover, header #lang_select ul li.active a{ color:#76AD2D; text-decoration:none !important; background:#2d2d2d; cursor:pointer; } +header #lang_select ul li.active a{ background:#444; } +header #lang_select ul li.current a{ background:url(/common/img/hdr/arrow_lang.png) 0px 3px no-repeat; } +header #lang_select .jScrollPaneTrack{ background:#292929; } +header #lang_select .jScrollPaneDrag{ background:url(/common/img/hdr/scrollbar_handle.png) top left no-repeat; } +header #lang_select .jScrollArrowUp{ background:url(/common/img/hdr/scrollarrow_up.png) top left no-repeat; width:14px; height:16px; } +header #lang_select .jScrollArrowDown{ background:url(/common/img/hdr/scrollarrow_down.png) top left no-repeat; width:14px; height:16px; } + +header.light { height:41px; background:transparent url(/common/img/hdr/bg-lighthdr.png) repeat-x top left; min-width:1018px; } +header.light ul#meta { right:12px; top:8px; } +header.light ul#meta li a { color:#fff; } +header.light ul#meta li#hdr_login { border-left: 1px solid #F6F6F6; } +header.light ul#meta li#meta_countrylang { display:none; } +header.light #logo { position:relative; top:8px;background:transparent url(/common/img/hdr/logo-lighthdr.png) no-repeat top left; width:53px; height:32px; padding:0px; } +header.light #logo a { width:53px; height:32px; } +header.light #lang_select { display:none; } +.nologin footer .footer_global { background-color:#202020; padding:9px 0; } +.nologin footer .footer_global a, .nologin footer .footer_global p { color: #666666 !important; } +.nologin header.light { height:60px; } +.nologin header.light #logo { top:18px; } + +#search_autocomplete{ position: absolute; top: 37px; background:#fff; right:20px; width: 136px; border-radius: 0px 0px 5px 5px; display:none; border-bottom:1px solid #f5f5f5; border-left:1px solid #f5f5f5; border-right:1px solid #f5f5f5; z-index:1000; box-shadow:0px 6px 9px #439539; } +#search_autocomplete ul, #search_autocomplete ul li{ margin:0; padding:0; list-style-type:none; } +#search_autocomplete ul{ padding:5px 0; } +#search_autocomplete ul li{ /*padding-bottom:4px;*/ } +#search_autocomplete ul li a{ text-decoration:none; color:#333; padding:5px 10px; display:block; } +#search_autocomplete ul li.active a{ background:#ceebcb; } + + +/* Home page +----------------------------------- */ +#banners{ background:url(/common/img/gray_dotted_home.png) top center repeat-y; } +#banners .wrap{ position:relative; min-height:272px; height:auto !important; height:272px; clear:both; } +#banners .banner{ display:none; min-height:272px; height:auto !important; height:272px; } +#banners .banner h1{ font-size:40px; line-height:37px; font-weight:200; } +#banners .banner h1 a{ text-decoration:none; color:#439539; } +#banners .banner h1 strong{ display:block; color:#333; font-weight:200; margin-bottom:10px; } +#banners .banner h1 span{ display:block; padding:4px 0 4px 20px; font-size:12px; line-height:12px; font-family:Helvetica, Arial, sans-serif; background:url(/common/img/arrow.png) 0px 3px no-repeat; } +#banners .banner h1 a:hover span{ text-decoration:underline; } +#banners #banner_nav{ position:absolute; top:15px; right:20px; } +#banners #banner_nav a{ width:10px; height:10px; background:#ddd; /*-moz-border-radius:5px; -webkit-border-radius:5px; border-radius:5px;*/ display:block; float:left; margin-left:5px; } +#banners #banner_nav a:hover{ background:#439539; } +#banners #banner_nav a.active{ background:#333; } + +#newsticker{ background:#7ac142; padding:8px 0; } +#newsticker p{ padding:0; color:#F1FFD6; line-height:100%; float:left; padding-right:10px; font-weight:bold; text-transform:uppercase; font-size:12px; } +#newsticker p a { color:#FFFFFF; text-decoration:none; } +#newsticker p a:hover { text-decoration:underline; } +#newsticker ul, #newsticker ul li{ margin:0; padding:0; list-style-type:none; } +#newsticker ul li{ display:none; float:left; line-height:100%; font-size:12px; } +#newsticker ul li a{ color:#F1FFD6; text-decoration:none; } +#newsticker ul li a:hover{ text-decoration:underline; } + +#hotoffers{ background:url(/common/img/gray_dotted_bg.png) top left repeat-x; padding:25px 0; } +#hotoffers .wrap{ overflow:hidden; } +#hotoffers #hotoffers_wrap{ width:1100px; } +.offer{ width:235px; height:175px; float:left; margin-right:13px; position:relative; } +.offer a{ width:235px; height:175px; display:block; text-decoration:none; color:#fff; font-size:16px; background:url(http://dummyimage.com/235x175) top left no-repeat; position:relative; } +.en-us .offer a{ font-size:18px; } +.offer a span{ font-weight:300; padding:16px; position:absolute; bottom:0px; left:0px; width:203px; line-height:16px; /*min-height:51px; height:auto !important; height:51px;*/ } +.en-us .offer a span{ font-weight:100; } +.offer_green a span{ background:#79BB46; opacity:0.9; -moz-opacity:0.9; filter:alpha(opacity=90); -moz-border-radius-bottomright: 2px; border-bottom-right-radius: 2px; -moz-border-radius-bottomleft: 2px; border-bottom-left-radius: 2px; } + +#trial_content{ padding:55px 0; } +#trial_content .trial_content_sub{ position:relative; padding-right:690px; /*background:url(/home/img/businesses.png) 353px 27px no-repeat;*/ } +#trial_content .trial_content_sub p{ padding-bottom:20px; } +#trial_content h2{ font-size:25px; line-height:24px; color:#439539; font-weight:100; padding-bottom:18px; } + +#trial_content .trial_content_sub ul, .trial_content_sub ul li{ margin:0; padding:0; list-style-type:none; } +#trial_content .trial_content_sub ul{ position:absolute; top:15px; right:0; } +#trial_content .trial_content_sub ul li{ float:left; border:none !important; margin-left:25px; } +#trial_content .trial_content_sub ul li a{ display:block; text-indent:-9999px; height:76px; background-position:top left; background-repeat:no-repeat; padding:0; } +#trial_content .trial_content_sub ul li#success_lse a{ width:158px; background-image:url(/home/img/success_lse.png); } +#trial_content .trial_content_sub ul li#success_od a{ width:134px; background-image:url(/home/img/success_od.png); } +#trial_content .trial_content_sub ul li#success_sony a{ width:114px; background-image:url(/home/img/success_sony.png); } +#trial_content .trial_content_sub ul li#success_wal a{ width:135px; background-image:url(/home/img/success_wal.png); } + + +#home_alliance{ border-top:1px solid #666; border-bottom:1px solid #666; padding:5px 0; margin-bottom:15px; } +#home_alliance p{ padding:0; font-size:12px; color:#666; float:left; width:165px; padding-top:11px; } +#home_alliance ul{ float:right; } +#home_alliance li{ border:none; width:auto; float:left; padding-left:25px; } + +#home_alliance li#home_alliance_amd a{ background-image:url(/common/img/alliance_partners/home/amd_alliance_sprite_s1.png); width:66px; } +#home_alliance li#home_alliance_fujitsu a{ background-image:url(/common/img/alliance_partners/home/fujitsu_alliance_sprite_s1.png); width:50px; } +#home_alliance li#home_alliance_hp a{ background-image:url(/common/img/alliance_partners/home/hp_alliance_sprite_s1.png); width:30px; } +#home_alliance li#home_alliance_ibm a{ background-image:url(/common/img/alliance_partners/home/ibm_alliance_sprite_s1.png); width:47px; } +#home_alliance li#home_alliance_dell a{ background-image:url(/common/img/alliance_partners/home/dell_alliance_sprite_s1.png); width:35px; } +#home_alliance li#home_alliance_intel a{ background-image:url(/common/img/alliance_partners/home/intel_alliance_sprite_s1.png); width:39px; } +#home_alliance li#home_alliance_ms a{ background-image:url(/common/img/alliance_partners/home/microsoft_alliance_sprite_s1.png); width:77px; } +#home_alliance li#home_alliance_oracle a{ background-image:url(/common/img/alliance_partners/home/oracle_alliance_sprite_s1.png); width:66px; } +#home_alliance li#home_alliance_sap a{ background-image:url(/common/img/alliance_partners/home/sap_alliance_sprite_s1.png); width:47px; } +#home_alliance li#home_alliance_vmware a{ background-image:url(/common/img/alliance_partners/home/vmware_alliance_sprite_s1.png); width:72px; } + +#home_alliance li a{ padding:0; background-position:top right; background-repeat:no-repeat; display:block; text-indent:-9999px; height:34px; } +#home_alliance li a:hover{ background-position:bottom right; } + + + + +/* Feature banner section (e.g. on product page) +----------------------------------- */ +.feature{ background:url(/common/img/green_dotted_bg.png) top left repeat; padding-top:43px; } +.feature h2{ color:#fff; font-size:28px; font-weight:300; } +.feature h2 a{ color:#fff; text-decoration:none; } +.feature h2 a:hover{ text-decoration:underline; } +.feature h2 span{ font-size:8px; } +.feature .links{ height:41px; position:relative; z-index:1; } +.feature_main .links{ border-bottom:1px solid #A6D838; } +.feature #product_nav, .feature #product_nav li, .feature #meta_nav, .feature #meta_nav li{ margin:0; padding:0; list-style-type:none; } +.feature #product_nav{ position:absolute; left:0; bottom:11px; width:850px; } +.feature #meta_nav{ position:absolute; right:0; bottom:11px; } +.feature #product_nav li{ float:left; margin-right:20px; font:12px Helvetica, Arial, sans-serif; margin-top:4px; } +.feature #product_nav li a{ color:#fff; text-decoration:none; } +.feature #product_nav li.active a, .feature #product_nav li.active a:hover{ color:#A5D838; } +.feature #product_nav li a:hover{ color:#E3EDD7; } + +.feature #meta_nav li{ padding-right:10px; margin-right:10px; border-right:1px solid #333; float:left; font-size:12px; } +.feature #meta_nav li.last-child{ border:none !important; margin:0; padding:0; } +.feature #meta_nav li a{ text-decoration:none; color:#333; } +.feature #meta_nav li a:hover{ text-decoration:underline; } + +.feature .headline{ padding:80px 0 0 166px; background-position:0 80px; background-repeat:no-repeat; font-size:42px; line-height:40px; width:500px; color:#fff; float:left; font-weight:300; min-height:210px; height:auto !important; height:210px; } +.feature .headline strong{ font-weight:500; } + +.feature #cta_links, .feature #cta_links li{ margin:0; padding:0; list-style-type:none; } +.feature #cta_links{ float:right; padding-top:88px; width:222px; } +.feature #cta_links li{ border-bottom:1px solid #fff; } +.feature #cta_links li a{ display:block; padding:4px 2px; text-decoration:none; color:#fff; font:12px Helvetica, Arial, sans-serif; } +.feature #cta_links li a:hover{ background:#fff; color:#439539; } +.feature #cta_links #cta{ position:relative; border:none; background:url(/common/img/gray_dotted_dark_bg.png) top left repeat; /*-moz-box-shadow:2px 2px #6f8a3a; -webkit-box-shadow:2px 2px #6f8a3a; box-shadow:2px 2px #6f8a3a;*/ margin-bottom:2px; } +.feature #cta_links #cta a{ display:block; background:url(/common/img/gray_dotted_dark.png) top left no-repeat; padding:5px 5px 11px 9px; color:#79BF43; font-size:23px; line-height:23px; font-weight:400; letter-spacing:0.3px; } +.feature #cta_links #cta a:hover{ /*text-shadow:0px 0px 10px #99c24e;*/ } +.feature #cta_links #cta span { position:absolute; top:-4px; right:8px; display:none; width: 9px; height: 9px; background:#78AB36; /*Should be 79BF43 when the bg images are color corrected*/ -webkit-transform: rotate(-45deg); -moz-transform: rotate(-45deg); -ms-transform: rotate(-45deg); -o-transform: rotate(-45deg); transform: rotate(-45deg); -webkit-transform-origin: 0 100%; -moz-transform-origin: 0 100%; -ms-transform-origin: 0 100%; -o-transform-origin: 0 100%; transform-origin: 0 100%; } +.ie6 .feature #cta_links #cta span, .ie7 .feature #cta_links #cta span{ display:none; } /* To do: create the triangle as an image, so no CSS3. IE gets jacked up */ + +.headline_links, .headline_links li{ margin:0; padding:0; list-style-type:none; } +.headline_links li{ float:left; font-size:12px; padding-left:13px; background:url(/common/img/bullets/list_icon.png) 0px 5px no-repeat; margin-right:35px; line-height:12px; } +.headline_links li a{ text-decoration:none; color:#fff; } +.headline_links li a:hover{ text-decoration:underline; } + +.subnav, .subnav li{ margin:0; padding:0; list-style-type:none; } +.subnav li{ float:left; margin-right:32px; padding-top:15px; font-family:Helvetica, Arial, sans-serif; font-size:12px; } +.subnav li a{ color:#6A972C; text-decoration:none; } +.subnav li a:hover{ text-decoration:underline; } +.subnav li.active a{ color:#333; } + +/* Content styles +----------------------------------- */ +#content p{ padding-bottom:20px; font-size:13px; line-height:110%; } +#content img + p, #content ul + p, #content ol + p{ padding-top:20px; } +#content p, #content li{ color:#5F5F5F; } +#content p a, #content li a{ color:#439239; text-decoration:underline; } +#content p a:hover, #content li a:hover{ color:#333; } +/*#content strong{ color:#439239; }*/ +#content{ margin-top:15px; padding-top:54px; background:url(/common/img/gray_dotted_bg.png) top left repeat-x; } +#content.content_short{ margin-top:0; } +h3{ font-size:28px; color:#439239; line-height:32px; font-weight:300; } +h4{ font-size:15px; color:#333; padding:18px 0; border-top:1px solid #333; font-weight:400; } +a.external{ background:url(/common/img/bullets/external.png) top right no-repeat; padding-right:19px; } + +#content .callout{ padding:36px 0; background-repeat:no-repeat; border-bottom:1px solid #eee; } +#content h3 + .callout, #content p + .callout{ border-top:1px solid #eee; margin-top:36px; } +.longtail_four #content .callout{ border:none; } +#content .callout_left{ padding-right:313px; background-position:center right; } +#content .callout_right{ padding-left:313px; background-position:center left; } +#content .callout p{ font-size:21px; line-height:21px; color:#333; padding:36px 0; font-weight:300; } +#content .callout_left p, #content .callout_right p{ padding:0; } +#content .callout_left p + ul, #content .callout_right p + ul{ padding-top:36px; } +#content .callout p strong{ font-weight:400; } +#content .callout p a{ text-decoration:none; color:#439539; } +#content .callout p a:hover{ text-decoration:underline; } +#content .callout ul, #content .callout ul li, #content ul.callout_links, #content ul.callout_links li, #trial_content ul, #trial_content ul li{ margin:0; padding:0; list-style-type:none; } +/*.callout ul{ padding-bottom:36px; }*/ +#content .callout ul li, #content ul.callout_links li, #trial_content ul li{ border-bottom:1px solid #f0f0f0; } +#content .callout ul li:first-child, #content ul.callout_links li:first-child, #trial_content ul li:first-child{ border-top:1px solid #f0f0f0; } +#content .callout ul li a, #content ul.callout_links li a, #trial_content ul li a{ display:block; background:url(/common/img/bullets/list_icon.png) 0px 11px no-repeat; padding:6px 15px 4px 15px; color:#439539; text-decoration:none; } +#content .callout ul li a:hover, #content ul.callout_links li a:hover, #trial_content ul li a:hover{ color:#999; } +#content ul.callout_links li.external a{ background-image:url(/common/img/bullets/external.png); padding-left:19px; background-position:0px 8px; } + +.product_index #content .col_half{ width:335px; } +#content p.intro_text{ font-size:15px; line-height:16px; } +#content .col_half .callout{ margin-top:20px; padding-bottom:0; border:none; background:url(http://dummyimage.com/335x240) top left no-repeat; padding-top:260px; } +#content .col_half .callout p{ padding-top:0; } +#content .callout_full{ padding-top:150px; background:url(http://dummyimage.com/705x130) top left no-repeat; margin-top:20px; } +#content .callout_full p{ padding:0; } + +#highlight_wrap{ border-top:1px solid #439539; padding-top:50px; } +.col_highlight_one{ width:280px; float:left; margin-right:32px; } +.col_highlight_two{ width:390px; float:left; } + +#content .col_highlight_one p{ font-size:18px; font-weight:400; color:#333; } +#content .col_highlight_one p a{ text-decoration:none; } +#content .col_highlight_one p a:hover{ text-decoration:underline; } +#content .col_highlight_one p strong{ font-weight:400; } + +#content .col_highlight_two ul, .col_highlight_two ul li{ margin:0; padding:0; list-style:none; } +#content .col_highlight_two li{ padding:28px 0; border-bottom:1px solid #f0f0f0; } +#content .col_highlight_two li:first-child{ padding-top:0; } +#content .col_highlight_two li.last-child{ border-bottom:none; } +#content .col_highlight_two li strong{ color:#333; display:block; } +#content .col_highlight_two li a{ text-decoration:none; } +#content .col_highlight_two li a:hover{ text-decoration:underline; } + +#content .sublinks, .sublinks li{ margin:0; padding:0; list-style-type:none; } +#content .sublinks{ padding:45px 0; } +#content .sublinks li{ padding:30px 0; border-bottom:1px solid #f0f0f0; color:#333; font-size:15px; line-height:16px; font-weight:300; } +#content .sublinks li.last-child{ border:none; } +#content .sublinks li strong{ display:block; font-size:19px; font-weight:400; } +#content .sublinks li a{ color:#439539; text-decoration:none; } +#content .sublinks li a:hover{ text-decoration:underline; } + +#content .trio_list{ border-top:1px solid #f0f0f0; } +.longtail #content .trio_list, .longtail #content .resource_library{ border:none !important; } +#content p.title{ font-size:28px; color:#439539; line-height:27px; padding:50px 0; font-weight:300; } +#content .trio_list ul, .trio_list ul li{ margin:0; padding:0; list-style-type:none; } +#content .trio_list ul li{ float:left; width:216px; margin-right:28px; } +.longtail #content .trio_list ul li{ margin-right:37px !important; } +#content .trio_list ul li.last-child, #content .trio_list ul li.third{ margin-right:0 !important; } +#content .trio_list ul li.third + li{ clear:left; } +#content .trio_list ul li img{ background:#f8f8f8; } +#content .trio_list ul li strong{ font-weight:bold; display:block; padding-top:10px; } +#content .trio_list ul li p{ color:#646464; font-size:13px; line-height:16px; padding:30px 0; } +#content .trio_list p.more, #content #success p.more{ border-top:1px solid #f0f0f0; border-bottom:1px solid #f0f0f0; font-size:13px; padding:0; } +#content .trio_list p.more a, #content #success p.more a{ padding:4px 3px; text-decoration:none; display:block; color:#439539; } +#content .trio_list p.more a:hover, #content #success p.more a:hover{ /*background:url(/common/img/green_dotted_bg.png) top left repeat;*/ color:#999; } +#content .trio_list p.external a span, #content #success p.more a span{ background:url(/common/img/bullets/external.png) center right no-repeat; padding-right:20px; } +.tier4_wide #content .trio_list ul li{ margin-bottom:32px; } + +#content .anchors, .content_left .anchors li, .content_left .anchor_content, .content_left .anchor_content li{ margin:0; padding:0; list-style-type:none; } +#content .anchors{ padding-top:43px; } +#content .content_left h3 + p{ padding-top:20px; } +#content .content_left h3 + h3{ padding-top:80px; } +#content .content_left p + .anchors{ padding-top:0; } +.technical_information #content .anchors, .faq #content .anchors, .resource_library #content .anchors, .news_and_commentary #content .anchors{ padding-top:0; } +#content .anchors li{ font-size:13px; /*font-family:Omnes_Light;*/ margin-bottom:4px; width:325px; line-height:16px; background:url(/common/img/bullets/subnav.png) 0px 3px no-repeat; padding-left:15px; } +#content .content_left .nowrap li{ width:auto; } +#content .anchors li.column_two, .content_left .anchor_content li.column_two{ margin-left:350px !important; } +#content .anchors li a{ text-decoration:none; color:#333; } +#content .anchors li a:hover{ color:#999; } +#content .content_left .anchor_content li{ font-size:13px; width:320px; line-height:16px; color:#606060; margin-top:32px; } +#content .content_left .anchor_content strong{ display:block; margin-bottom:10px; font-weight:500; font-size:15px; color:#333; } +#content .content_left .anchor_content li a{ text-decoration:none; } +#content .content_left .anchor_content li a:hover{ text-decoration:underline; } +#content .content_left .anchor_content li ul, #content .content_left .anchor_content li ol{ padding:15px 0; } +#content .content_left .anchor_content li li{ margin:0 0 0 1em; list-style-type:disc; width:auto; } + +#content .anchor_active{ padding-top:55px !important; } +#content .anchor_active span{ padding:10px 10px 8px 10px; background:#f6c747; } + +#content .content_left .anchor_title{ margin-top:39px; padding:45px 0 30px 0; background-position:top left; background-repeat:no-repeat; font-size:18px; color:#333; font-weight:500; border-bottom:1px solid #f0f0f0; background-image:url(http://dummyimage.com/62x36.jpg); } +#content .content_left ul + .anchor_title{ margin-top:59px; } +#content .content_left .anchor_title + p{ padding:20px 0; } +#content .active_hash > span{ background-color:#ffd324; background-image: -webkit-gradient(linear, left bottom, left top, color-stop(0.55, rgb(243,184,36)), color-stop(0.78, rgb(255,211,35))); background-image: -moz-linear-gradient(center bottom,rgb(243,184,36) 55%,rgb(255,211,35) 78%); padding:10px; display:block; } + +blockquote{ font-weight:500; font-style:italic; font-size:25px; padding:40px 0; } +blockquote span{ font-weight:400; font-style:italic; font-size:80px; color:#7BBD46; display:block; float:left; margin:-12px 60px 0 60px; } +blockquote span sup{ font-size:30px; top:-1em; } + +blockquote.quote{ font-style:italic; font-size:16px; line-height:17px; font-weight:400; padding:36px 0; border-top:4px solid #439539; border-bottom:4px solid #439539; margin-top:36px; } +blockquote.quote strong{ display:block; margin-top:20px; font-style:normal; font-family:Helvetica, Arial, sans-serif; color:#333; font-size:12px; font-weight:bold; } +blockquote.quote span{ font-style:normal; font-family:Helvetica, Arial, sans-serif; font-weight:normal; font-size:12px; color:#333; margin:0; float:none; } + +/* Products/services +----------------------------------- */ +.products_services h3, .downloads_index h1, .training_index h1{ padding-bottom:20px; border-bottom:1px solid #439539; margin-bottom:100px; } +.products_services h4{ font-size:28px; margin:0; padding:0 0 20px 0; font-weight:400; border:0; } +.products_services h5, .downloads_index h3, .training_index h2{ padding:10px; margin:18px 0; text-transform:uppercase; color:#fff; font-size:14px; background:#bababa; line-height:100%; font-weight:normal; } +.products_services .even h5, .downloads_index h3, .training_index .even h2{ background:#8AC33C; } +.products_services #content p.title{ padding:10px 0; } + +.products_services #content .product_list, .products_services .product_list li{ margin:0; padding:0; list-style-type:none; } +.products_services #content .product_list{ width:520px; } +.products_services #content .product_list li{ width:222px; margin:50px 32px 0 0; float:left; padding-top:85px; background:url(http://dummyimage.com/72x72) top left no-repeat; } +.products_services #content .product_list li.even, .downloads_index #content .product_list li.fourth{ clear:left; } +.products_services #content .product_list li p.title{ font-weight:400; color:#439539; font-size:16px; padding-bottom:10px; line-height:17px; } +.products_services #content .product_list li p.links{ color:#E1E4E0; border-top:1px solid #f0f0f0; border-bottom:1px solid #f0f0f0; padding:4px 0; font-size:12px; } +.products_services #content .product_list li a{ text-decoration:none; } + +.products_services #content .callout_links{ padding-bottom:18px; } +.products_services .product_break + h5{ margin-top:50px; } + +.products_services #content .anchors{ padding-top:0; } + +/* Alternate product index design +----------------------------------- */ +.product_index_alt .headline{ font-size:18px; line-height:18px; background-position:0 40px; padding-top:40px; min-height:170px; height:auto !important; height:170px; } +.product_index_alt .headline strong{ font-size:36px; line-height:36px; display:block; font-weight:400; } +.product_index_alt .feature #cta_links{ padding-top:48px; } +.product_index_alt #content h3, .product_index_alt #content .trio_list .title{ border-top:1px solid #439539; font-size:15px; line-height:17px; font-weight:400; padding:15px 0; } + +.product_index_alt #content .highlight{ padding:47px 110px 47px 167px; background:url(http://dummyimage.com/70x70) 47px 51px no-repeat; border-bottom:1px solid #F0F0F0; } +.product_index_alt #content .highlights .highlight.last-child{ border:none; } +.product_index_alt #content .highlight h4{ color:#333; font-weight:500; margin:0; padding:0; border:none; font-size:17px; line-height:21px; } +.product_index_alt #content .highlight p{ color:#656565; font-weight:400; margin:0; padding:0; font-size:17px; line-height:21px; } +.product_index_alt #content .highlight p a{ text-decoration:none; } +.product_index_alt #content .highlight p a:hover{ text-decoration:underline; } +.product_index_alt #content .highlight ul, .product_index_alt .highlight ul li{ list-style-type:none; } +.product_index_alt #content .highlight ul{ padding-top:20px; margin:0; } +.product_index_alt #content .highlight ul li{ float:left; font-size:12px; padding-left:13px; background:url(/common/img/bullets/list_icon.png) 0px 5px no-repeat; margin-right:20px; } +.product_index_alt #content .highlight ul li a{ text-decoration:none; color:#439539; } +.product_index_alt #content .highlight ul li a:hover{ text-decoration:underline; } + +.product_index_alt #content .trio_list{ border:none; } +.product_index_alt #content .trio_list .title{ margin:20px 0 50px 0; } + +.product_index_alt #content{ padding-top:27px; } +.product_index_alt .feature #cta_links #cta a{ padding:0 22px 3px 8px; font-size:21px; } + +/* Longtail page content +----------------------------------- */ +.tier4 h1{ font-size:28px; color:#439239; line-height:32px; font-weight:300; } +.tier4 #content .content_left h1{ border-bottom:0; border-top:1px solid #439539; padding:15px 0 30px 0; } + +.longtail #content h3, +.comparison #content h3, +.technical_information #content h3, +.how_to_buy #content h3, +.faq #content h3, +.services_support #content h3, +.resource_library #content h3, +.news_and_commentary #content h3, +.tier4 h1, +.app h1{ border-bottom:1px solid #439239; padding-bottom:7px; /*padding-right:200px;*/ margin-bottom:60px; } +.longtail #content .content_right hr{ height:1px; font-size:1px; line-height:1px; border:none; background:#000; margin:22px 0; } + +#content .subtitle{ font-weight:500; color:#333; font-size:15px; } +#content p + p.subtitle{ padding-top:12px; } +#content p.subtitle + blockquote{ margin-top:0; } +.longtail #content .col_small li{ color:#333; font-size:13px; margin-bottom:5px; } +.longtail #content .col_small li ul, .longtail #content .col_small li ol, .content_left li ul, .content_left li ol{ padding:15px 0; } +/*.longtail #content .col_small li ul a, .longtail #content .col_small li ol a{ font-weight:bold; }*/ +.longtail #content h4, .services_support #content h4{ font-size:21px; padding:0; border:none; padding-bottom:20px; } +.longtail_two #content h4, .longtail_three #content h4, .longtail_four #content h4{ font-size:18px; padding-bottom:60px; } +.longtail #content h4 a, .services_support #content h4 a{ color:#439539; } + +.longtail_four h3, #solution.longtail_four h3, #solution.solution_industry h3, #solution.solution_platform h3{ padding:90px 350px 90px 0; background-position:right center; background-repeat:no-repeat; } +.longtail_four #content h4{ padding-bottom:36px; } +.longtail_four #content hr + h4{ padding-top:20px; } +.longtail_four #content{ margin-top:0 !important; } +.longtail_four .share{ float:none; margin-bottom:36px; } + +.tier4 .content_left{ width:640px; margin-right:115px; } +.tier4_wide .content_left{ width:723px; margin-right:32px; } + +.tier4 .content_short .content_right h2{ font-size:15px; color:#333; padding:18px 0; border-top:1px solid #333; font-weight:400; } +.tier4 #content .content_right .callout_links{ padding-bottom:32px; } + +#solution.longtail .content_left h4{ border:none; padding:0 0 60px 0; margin:0; } +#solution.longtail .content_left .col_half{ padding-top:0; } + +.greenbox{ width:84px; background:#98C109; position:absolute; right:0; } +#content .greenbox p{ text-align:center; padding:15px 10px; } +#content .greenbox p.number{ font-weight:300; font-size:43px; color:#fff; padding-bottom:5px; position:relative; } +#content .greenbox p.number sup{ font-size:22px; } +#content .greenbox p.text{ font-weight:500; font-size:11px; border-top:1px dotted #cfdb89; color:#333; } +#content .greenbox p span{ position:absolute; top:28px; right:-15px; display:block; width:17px; height:17px; background:#98C109; -webkit-transform: rotate(-45deg); -moz-transform: rotate(-45deg); -ms-transform: rotate(-45deg); -o-transform: rotate(-45deg); transform: rotate(-45deg); -webkit-transform-origin: 0 100%; -moz-transform-origin: 0 100%; -ms-transform-origin: 0 100%; -o-transform-origin: 0 100%; transform-origin: 0 100%; z-index:-1; } + +#content .col_small blockquote{ font-weight:400; font-style:italic; font-size:23px; color:#333; padding-right:32px; border-right:5px solid #eee; text-align:right; position:absolute; right:0; } + +/* Comparison page +----------------------------------- */ +.comparison #content h4{ font-size:18px; padding:0; border:none; padding-bottom:40px; } + +.table_comparison{ width:100%; border-collapse:collapse; border-spacing:0; margin-bottom:20px; } +.table_comparison thead th{ background:#efefef; height:125px; vertical-align:middle; width:165px; line-height:1px; border-right:1px solid #fff; } +.table_comparison thead th.null{ width:auto; border:none; } +.table_comparison thead th:first-child{ background:#f3f3f3; } +.table_comparison thead th.last-child{ border:none; } +.table_comparison tbody td{ vertical-align:middle; text-align:left; padding:30px 0; color:#333; font-weight:500; font-size:15px; border-right:1px solid #e9e9e9; border-bottom:1px solid #e9e9e9; } +.table_comparison tbody td a{ color:#439539; text-decoration:underline; } +.table_comparison tbody td a:hover{ color:#999; } +.table_comparison tbody td span{ display:block; text-align:center; } +.table_comparison tbody td span.no{ display:none; } +.table_comparison tbody td span.na{ color:#999; } +.table_comparison tbody td span.yes, .table_comparison tbody td span.half{ background:url(/common/img/comparison.png) bottom center no-repeat; text-indent:-9999px; height:14px; } +.table_comparison tbody td span.half{ background-position:top center; } + +.version_comparison thead th{ width:335px; } +.version_comparison tbody td{ vertical-align:top; padding-left:20px; font-size:13px; } +.version_comparison tbody td.title{ padding-left:0; font-size:15px; } +.version_comparison tbody td li{ color:#333 !important; } +.version_comparison tbody td span{ color:#439239; font-weight:500; font-style:italic; padding-right:5px; display:inline; } + +/* Technical information +----------------------------------- */ +.technical_information #content .content_left .col_half, .resource_library #content .content_left .col_half{ width:318px; } +.technical_information #content .content_left .anchor_title{ padding-top:0; background:none; } +#content .table_header{ background:#95ba4d; font-size:15px; color:#fff; padding:13px 15px 15px 15px; margin:15px 0; font-weight:500; } +#content .table_header strong{ color:#fff; } +#content .table_header span{ display:block; font-size:12px; color:#333; } +.table_text thead th{ height:auto; line-height:100%; padding:5px 0; width:auto; } +.table_text thead th.null{ width:150px; } +.table_text thead th:first-child{ border-right:1px solid #fff; } +.table_text tbody td{ padding:15px; font-size:13px; vertical-align:top; } +.table_text tbody td.title{ padding:15px 5px 15px 0; color:#439539; } +.table_text tbody td p{ padding:0 20px; font-size:15px; } + +/* FAQ +----------------------------------- */ +.faq #content .anchor_title{ padding:0; background:none; border:none; font-size:15px; } +.faq .contact{ margin-top:20px; } +.faq .contact p{ clear:both; padding-top:10px; } +.faq .contact label{ width:150px; float:left; text-align:right; margin-right:15px; display:block; padding-top:4px; } +.faq .contact input, .faq .contact textarea{ float:left; width:300px; margin:0; padding:4px; border:1px solid #eee; } +.faq .contact p#submit{ background:url(/common/img/green_dotted_bg.png) top left repeat; float:right; padding:0; margin:10px 230px 0 0; } +.faq .contact p#submit input{ width:auto; padding:4px 12px 3px 12px; background:url(/common/img/green_dotted_bg.png) top left repeat; border:none; color:#fff; cursor:pointer; } + +/* Services and support +----------------------------------- */ +.services_support #content .anchor_title{ padding-top:0; background:none; padding-bottom:12px; margin-bottom:32px; } +.services_support #content .content_left .anchor_title:first-child{ margin-top:0; } + +/* Resource library +----------------------------------- */ +.resource_library #content .anchor_title{ padding-bottom:15px; margin-bottom:25px; } +.resource_library #content p#Downloads{ background-image:url(/common/img/resources_download.png); } +.resource_library #content p#AV{ background-image:url(/common/img/resources_av.png); } +.resource_library #content p#Flyers{ background-image:url(/common/img/resources_flyer.png); } +.resource_library #content p#WhitePapers{ background-image:url(/common/img/resources_whitepaper.png); } +.resource_library #content p#Demos{ background-image:url(/common/img/resources_demo.png); } +.resource_library #content p#Data_Sheets { background-image:url(/common/img/resources_datasheet.png); } +.resource_library #content p#FAQ { background-image:url(/common/img/resources_faq.png); } + +/* News/commentary +----------------------------------- */ +.news_and_commentary #content .anchor_title{ padding-top:0; background:none; padding-bottom:15px; margin-bottom:25px; } + +/* How to buy page +----------------------------------- */ +#cpu_form{ margin-top:32px; } +#cpu_form label, #cpu_form select{ float:left; } +#cpu_form label{ font-size:28px; display:block; margin-right:15px; } +#cpu_form select{ margin-top:5px; } + +.support_comparison thead th{ width:200px; padding:15px 0; text-align:left; } +.support_comparison thead th img{ float:left; margin-left:27px; } +.support_comparison thead th span{ float:left; display:block; padding:10px 0 0 15px; font-size:15px; color:#666; font-weight:normal; line-height:16px; } +/*.support_comparison .buy{ display:none; }*/ +.support_comparison .buy td{ background:#666; border-right:1px solid #999; border-bottom:1px solid #999; padding:10px 15px !important; color:#fff !important; text-align:left; } +.support_comparison .buy td div{ position:relative; } +.support_comparison .buy td span{ display:inline; text-align:left; } +.support_comparison .buy a{ background:#95ba4d; font-size:11px; color:#fff; text-decoration:none; padding:2px 8px 3px 8px; /*position:absolute; top:0; right:0;*/ border-radius:3px; -moz-border-radius:3px; font-weight:500; float:right; } +.support_comparison .buy a:hover{ box-shadow: 0 0 5px #333; -webkit-box-shadow: 0 0 5px #333; -moz-box-shadow: 0 0 5px #333; color:#fff; background:#95BA4D; } +.support_comparison .buy a:active{ background:#76AD2D; } + +/* Promo +----------------------------------- */ +#content .content_right .promo{ margin-top:20px; } +#content .content_right .promo p{ padding:0; font-size:15px; } +#content .content_right .promo p a{ display:block; padding:15px 100px 15px 15px; text-decoration:none; color:#fff; background:#333 url(/common/img/support_standard.png) 150px 10px no-repeat; } +#content .content_right .promo p a:hover{ background-color:#444; } +#content .content_right .promo p a strong{ display:block; color:#439539; } + +#promo_container{ border-top:1px solid #333; padding:0 0 30px 0; border:none; position:relative; } +#promo_wrapper{ border-top:1px solid #439539; border-bottom:1px solid #439539; } +#promo_container .promo_single{ padding-bottom:0; display:none; } +#promo_container .promo_single a{ text-decoration:none; color:#439539; } +#promo_container .promo_single strong{ display:block; font-family:"omnes-pro-1"; color:#439539; font-size:19px; line-height:20px; font-weight:400; padding:32px 15px 7px 15px; } +#promo_container .promo_single span{ padding:0 15px; text-decoration:none; color:#646464; font-size:11px; margin-bottom:25px; display:block; } +#promo_container .promo_single img{ display:block; } +#promo_container #promo_nav{ position:absolute; bottom:10px; right:0; } +#promo_container #promo_nav a{ width:10px; height:10px; background:#ddd; /*-moz-border-radius:5px; -webkit-border-radius:5px; border-radius:5px;*/ display:block; float:left; margin-left:5px; } +#promo_container #promo_nav a:hover{ background:#439539; } +#promo_container #promo_nav a.active{ background:#333; } + + +/*.promo_sidebar{ border-top:1px solid #333; padding-top:18px; }*/ +.promo_sidebar a{ border-top:3px solid #7ac142; border-bottom:3px solid #7ac142; display:block; text-decoration:none !important; padding:32px 18px 130px 18px; background:url(/common/img/promo/geeko_zpromo.png) bottom right no-repeat; } +.promo_sidebar a strong{ display:block; color:#439539; font-size:18px; margin-bottom:12px; font-weight:400; } +.promo_sidebar a span{ display:block; color:#666; font-size:12px; } +.promo_sidebar a:hover{ background-color:#fafafa; } + +/* Solution +----------------------------------- */ +#solution .feature li a, .sap .feature #product_nav li a{ color:#ccc; } +.event #product_nav li a{ color:#fff; } +#solution .feature li.active a, .sap .feature #product_nav li.active a, #solution .feature #product_nav li a:hover, .sap .feature #product_nav li a:hover{ color:#7ac142; } +#solution .feature_main .links{ border-bottom:1px solid #7ac142; } +#solution .feature{ background-image:url(/common/img/black_dotted_bg.png); background-color:#323232; } +#solution .feature .headline{ float:none; width:auto; padding:50px 0 30px 0; font-size:29px; line-height:31px; color:#7ac142; min-height:0; } +#solution .feature p{ color:#fff; padding-bottom:60px; width:650px; } + +#solution_selection{ padding-top:20px; } +#solution_selection ul, #solution_selection ul li, .solution_list, .solution_list li{ margin:0; padding:0; list-style-type:none; } +#solution_selection ul li, #content .solution_list li{ background:url(/common/img/solution_separator.png) center right no-repeat; float:left; padding:20px 25px 0 25px; text-align:center; } +#solution_selection ul li a, #content .solution_list li a{ display:block; padding-top:85px; background:url(http://dummyimage.com/85x75) top center no-repeat; min-width:85px; width:auto !important; width:85px; text-decoration:none; color:#439539; } +#solution_selection ul li a:hover, #content .solution_list li a:hover{ color:#999; } +#solution_selection ul li a span, #content .solution_list li a span{ padding-left:13px; background:url(/common/img/bullets/subnav.png) 0px 4px no-repeat; } +#solution_selection .solution_sub li{ background:none; padding:0 25px 0 0; } +#solution_selection .solution_sub li a{ background:none; padding-top:0; min-width:0; } + +#solution_selection p{ padding:50px 0 0 20px; float:left; } +#solution_selection p a{ text-decoration:none; color:#439539; } +#solution_selection p a:hover{ color:#999; } + +.solution_index #content hr{ border-color:#439539; } +.solution_index #content .solution_list li{ width:182px; text-align:left; } +.solution_index #content .solution_list li:first-child{ padding-left:0; } +.solution_index #content .solution_list li.last-child{ background:none; } +.solution_index #content .solution_list li a{ background-position:top left; } + +#solution .content_left .col_half{ padding-top:60px; width:336px; } +#solution h3{ padding-bottom:15px; } +#solution .col_half a{ text-decoration:none; } +#solution .col_half .callout_links{ padding-bottom:25px; } + +#solution.solution_index hr{ background:#439539; margin:3em 0; } +#solution.solution_industry h3, #solution.solution_platform h3{ padding:0 0 20px 0; border-top:none; border-bottom:1px solid #439539; margin-bottom:30px; display:none; } +#solution.solution_industry .content_left h4, #solution.solution_platform .content_left h4{ font-size:28px; font-weight:300; color:#439539; border-top:1px solid #439539; padding-top:50px; } +#solution .content_left h5{ border-top:none; padding-top:0; font-weight:500; border-bottom:1px solid #f0f0f0; padding-bottom:10px; margin-bottom:20px; font-size:18px; } +#solution .content_left h6{ font-size:16px; font-weight:500; padding:10px 0 15px 0; } + +#content .box{ background:#729D3A; padding:20px; } +#content .box { background:#729D3A; padding:20px; } +#content .box .col_half{ padding-top:0; width:315px; } +#content .box p{ color:#fff; font-size:11px; } +#content .box p.box_title{ font-size:16px; font-weight:400; padding-bottom:10px; } +#content .box p.box_link{ border-top:1px solid #fff; text-align:right; font-size:13px; padding:5px 0 0 0; } +#content .box p.box_link a{ color:#333; background:url(/common/img/bullets/list_icon.png) 0px -10px no-repeat; padding-left:13px; } +#content .box p.box_link a:hover{ text-decoration:underline; } + +.anchor_top{ display:block; float:right; padding-left:13px; background:url(/common/img/bullets/subnav.png) 0px -31px no-repeat; text-decoration:none; color:#439539; margin-top:30px; } +.anchor_top:hover{ text-decoration:underline; } +#product .anchor_top{ margin-top:40px; } + +.solution_industry h3{ padding:45px 0 20px 0; border-top:1px solid #439539; } +.solution_industry .col_half{ padding:0 0 30px 0 !important; } + +.solution_industry #content .company{ border-top:1px solid #333; padding:20px 0; } +.solution_industry #content .company > p{ float:left; width:110px; margin-right:15px; } +.solution_industry #content .company .company_info{ float:left; width:210px; } +.solution_industry #content .company .company_info p{ font-weight:bold; padding-bottom:5px; border-bottom:1px solid #f0f0f0; color:#333; margin-bottom:15px; } +.solution_industry #content .company .company_info p.desc{ font-weight:normal; padding-bottom:10px; border:none; color:#333; } +.solution_industry #content .company ul.company_products, .solution_industry #content .company ul.company_products li{ margin:0; padding:0; list-style-type:none; } +.solution_industry #content .company ul.company_products{ padding-bottom:10px; } +.solution_industry #content .company ul.company_products li{ padding:5px 0; color:#666; } + +#solution blockquote.quote{ border:none; padding:0; margin:18px 0; } + +/* Partners +----------------------------------- */ +#partner .feature{ /* background:#618c2a url(/common/img/partners/partner_greendotted_bg.png) top left repeat-x; */ padding-top:0; } +#partner .feature_sub{ background-position:top center; background-repeat:no-repeat; padding-top:43px; } +#partner .feature_cloud{ background-image:url(/common/img/partners/linecloud_bg.png); } +/*#partner .feature_appliance{ background-image:url(/common/img/partners/linecloud_bg.png); }*/ +#partner .feature .headline{ padding:69px 0 0 0; width:650px; min-height:199px; height:auto !important; height:199px; } +#partner .feature #cta_links #cta span{ background:#618c2a; } +#partner .feature #cta_links{ padding-top:77px; } + +#partner_main #content{ margin-top:0; } +#partner_main h1{ font-size:28px; color:#439239; line-height:32px; font-weight:300; border-bottom:1px solid #439239; padding-bottom:7px; /*padding-right:200px;*/ margin-bottom:60px; } +#partner_main .content_left h2{ font-size:28px; font-weight:400; margin:0; padding:0 0 20px 0; border:none; } +#partner_main .content_left h3{ font-size:16px; font-weight:500; margin:0; padding:20px 0 10px 0; color:#333; line-height:17px; } +#partner_main .content_left p a{ text-decoration:none; } +#partner_main .content_left p a:hover{ text-decoration:underline; } +#partner_main .content_right ul.callout_links{ padding-bottom:20px; } + +#content .suse_button a{ display:inline-block; padding:5px 15px; color:#fff; text-decoration:none; background:url(/common/img/green_dotted_bg.png) top left repeat; } +#content .suse_button a:hover{ text-decoration:underline; color:#fff; } +.indent{ padding-left:55px; } + +.appliance_pavilion #content h3{ margin-bottom:30px; padding-bottom:10px; border-bottom:1px solid #439539; } +.appliance_pavilion #content .content_left h4{ padding:0; border:none; font-weight:500; margin-bottom:30px; } +.appliance_pavilion #content .anchors{ padding-top:0; } + +.appliance_pavilion .pavilion_partner{ padding-top:45px; border-top:1px solid #e0e0e0; margin-top:45px; } +.appliance_pavilion .pavilion_one{ width:133px; float:left; margin-right:32px; } +.appliance_pavilion .pavilion_two{ width:300px; float:left; margin-right:32px; } +.webcasts .pavilion_two{ width:540px; margin-right:0; } +.appliance_pavilion .pavilion_three{ width:208px; float:left; } + +.appliance_pavilion .pavilion_two blockquote{ padding:22px 0; border-top:2px solid #e0e0e0; border-bottom:2px solid #e0e0e0; font-style:italic; font-size:12px; font-family:Helvetica, Arial, sans-serif; } +.appliance_pavilion .pavilion_two blockquote strong{ font-style:normal; display:block; padding-top:15px; } +.appliance_pavilion .pavilion_two blockquote span{ font-style:normal; color:#333; font-size:12px; font-family:Helvetica, Arial, sans-serif; float:none; margin:0; } +.appliance_pavilion #content .content_right h4{ border-top:1px solid #333; font-weight:400; padding:18px 0; font-size:15px; } +.appliance_pavilion #content .content_right .callout_links{ padding-bottom:25px; } + +.appliance_pavilion #content .content_right .promo { position:relative; width:222px; height:95px; margin:0; } +.appliance_pavilion #content .content_right .promo a{ background:none; padding:0; } +.appliance_pavilion #content .content_right .promo a:hover{ background:none; } +.appliance_pavilion #content .content_right .promo a strong{ display:inline !important; } +.appliance_pavilion #content .content_right p.promo_1 a { font-size:13px; position:absolute; left:8px; top:4px; } +.appliance_pavilion #content .content_right p.promo_2 a { font-size:11px; position:absolute; left:8px; top:10px; line-height:13px; } +.appliance_pavilion #content .content_right p.promo_3 a { font-size:14px; position:absolute; left:8px; top:14px; } +.appliance_pavilion #content .content_right .largetxt { font-size:13px !important; line-height:15px !important; color:#CEE4A4 !important; } +.appliance_pavilion #content .content_right p.promo_2 span.readnow { font-size:12px; color:#47555E; position:absolute; top:55px; } +.appliance_pavilion #content .content_right p.promo_3 span.try { color:#CCDFA6; font-size:13px; font-weight:normal; position:absolute; top:39px; } + +.alliance_partners_index .feature p a, .alliance_partners .feature p a{ color:#7AC142; text-decoration:none; } +.alliance_partners_index .feature p a:hover, .alliance_partners .feature p a:hover{ text-decoration:underline; } +.alliance_partners_index .trio_list li{ margin-bottom:32px; } +#solution.alliance_partners_index blockquote.quote{ padding:22px 0; border-top:2px solid #e0e0e0; border-bottom:2px solid #e0e0e0; font-size:18px; font-style:normal; color:#439539; line-height:20px; } +#solution.alliance_partners_index blockquote.quote strong{ font-style:normal; display:block; padding-top:15px; text-align:right; } +#solution.alliance_partners_index blockquote.quote span{ font-style:normal; color:#333; font-size:12px; font-family:Helvetica, Arial, sans-serif; float:none; margin:0; text-align:right; } +.alliance_partners h3{ font-size:19px; line-height:21px; color:#5F5F5F; padding:32px 0 !important; border-top:3px solid #7ac142; font-weight:400; } +.alliance_wrap{ padding:32px 0; border-top:2px solid #ddd; } +.alliance_one{ float:left; width:140px; margin-right:32px; } +.alliance_one h4{ color:#333; font-size:19px; line-height:21px; font-weight:500; padding:0; border:none; } +.alliance_two{ float:left; width:220px; margin-right:32px; } +.alliance_three{ float:left; width:280px; } +.alliance_wrap .col_half{ padding-top:15px !important; } + +.alliance_two_small, .alliance_three_small, .alliance_four_small{ float:left; width:160px; margin-right:25px; } +.alliance_four_small{ margin-right:0; } + +#solution .feature_alliance .headline{ width:600px; } +#solution .feature_alliance #alliance_banner_img{ float:right; margin-top:55px; } + + +/* Press +----------------------------------- */ +.press h3{ margin-bottom:25px; } +.content_left_one{ width:120px; float:left; margin-right:10px; } +.content_left_one h4{ font-size:20px; font-weight:400; } +.content_left_two{ width:565px; float:left;} +.press .content_left hr{ margin:3em 0; } + +/* SAP customization +----------------------------------- */ +.sap .feature{ background-image:url(/common/img/black_dotted_bg.png); background-color:#323232; } +.sap .feature_main .links{ border-bottom:1px solid #9ECD38; } +.sap .feature #meta_nav li{ border-right:1px solid #fff; } +.sap .feature #meta_nav li a{ color:#fff; } +.sap .feature #cta_links #cta{ box-shadow:2px 2px #0a3f73; -moz-box-shadow:2px 2px #0a3f73; -webkit-box-shadow:2px 2px #0a3f73; } +.sap .feature #cta_links #cta a{ color:#2380bf; } +.sap .feature #cta_links #cta span{ background:#004486; } +.sap .feature .headline{ font-size:35px; line-height:33px; padding-left:196px; } +.sap .feature .headline p{ padding-bottom:15px; color:#9ECD38; } + +.sap_sles #content .sublinks{ padding-bottom:0; } +.sap_sles #content h3{ font-size:18px; color:#333; font-weight:400; border-top:1px solid #439539; padding:50px 0; } +.sap_sles #content h4{ margin-top:20px; } +.sap_sles #content .content_left h4{ border-top:1px solid #439539; color:#439539; } +.sap_sles #content .sublinks{ padding:0 0 30px 0; margin-left:1em; } +.sap_sles #content .sublinks li{ border:none; font-size:13px; list-style-type:disc; padding:0; color:#666; font-family:Helvetica, Arial, sans-serif; margin-bottom:8px; } +.sap_sles #content .sublinks li strong{ display:inline; font-size:15px; color:#333; font-weight:500; } +.sap_sles #content .sublinks li strong:after{ content:" \2014 "; } +.sap_sles #content #industry_experts li{ font-size:11px; border-top:none !important; } + +/* Event page +----------------------------------- */ +.event .feature{ /*padding-bottom:15px;*/ padding-top:26px; } +.event .feature .links{ height:auto; padding-top:15px; } +.event h2{ padding-bottom:15px; } +.event h2 span{ font-family:Arial; font-size:12px; color:#999; } +.event .links{ border:none !important; } +.event #content{ margin-top:0; padding-top:32px; } +.event #product_nav{ position:static; top:auto; left:auto; bottom:auto; } +.event #product_nav li{ margin-top:0; padding-bottom:10px; } + +.event .col_left{ float:left; width:720px; margin-right:32px; padding-top:50px; } +.event .col_left_mini{ float:left; width:145px; margin-right:20px; } +.event .col_left_large{ float:left; width:500px; } +.event .col_right{ float:left; width:222px; padding-top:50px; } +.event .col_right h3{ color:#666; } +.event .col_right h4{ color:#666; padding-top:15px; border-top:1px solid #000; } + +.event hr{ border:none; } +.event p.cta{ float:right; } +.event p.cta a{ color:#fff !important; display:inline-block; background:url(/common/img/green_dotted_bg.png) top left repeat; display:block; text-decoration:none !important; padding:4px 12px 5px 12px; } + +.event #content #accordion{ padding-bottom:25px; } +.event #content .accordion_header{ background:#f4f4f4; padding:10px 15px; color:#999; font-size:11px; border-top:1px solid #fff; border-bottom:1px solid #e7e7e7; cursor:pointer; } +.event #content .accordion_header strong{ color:#211f1f; } +.event #content .accordion_body{ background:#fdfdfd; padding:15px; color:#505253;} +.event #content .accordion_body p{ margin:0; padding:0 0 10px 0; font-size:11px; } + +#solutions_follow{ padding-bottom:15px; } +#content #solutions_follow h3{ color:#000; border-top:1px solid #000; padding:15px 0; font-size:13px; } +#content #solutions_follow ul, #content #solutions_follow ul li{ margin:0; padding:0; list-style-type:none; } +#content #solutions_follow ul li{ width:24px; height:24px; margin:0 10px 10px 0; float:left; } +#content #solutions_follow li a{ width:24px; height:24px; display:block; text-indent:-9999px; background-position:top left; background-repeat:no-repeat; } +#content #solutions_follow li a:hover{ background-position:bottom left; } +#solutions_follow li#sf_cool a{ background-image:url(http://www.novell.com/common/img/follow/cool.jpg); } +#solutions_follow li#sf_email a{ background-image:url(http://www.novell.com/common/img/follow/email.jpg); } +#solutions_follow li#sf_fb a{ background-image:url(http://www.novell.com/common/img/follow/fb.jpg); } +#solutions_follow li#sf_forum a{ background-image:url(http://www.novell.com/common/img/follow/forum.jpg); } +#solutions_follow li#sf_google a{ background-image:url(http://www.novell.com/common/img/follow/google.jpg); } +#solutions_follow li#sf_quote a{ background-image:url(http://www.novell.com/common/img/follow/quote.jpg); } +#solutions_follow li#sf_rss a{ background-image:url(http://www.novell.com/common/img/follow/rss.jpg); } +#solutions_follow li#sf_twitter a{ background-image:url(http://www.novell.com/common/img/follow/twitter.jpg); } +#solutions_follow li#sf_url a{ background-image:url(http://www.novell.com/common/img/follow/url.jpg); } + +.event #content #events_related p{ font-size:11px; } +.event #content #events_related a{ font-weight:bold; color:#333; display:block; text-decoration:none; } +.event #content #events_related a:hover{ text-decoration:underline; } + +.event .feature{ background:url(/common/img/green_dotted_bg.png) top left repeat !important; padding-top:75px; } + +.event .meta{ position:relative; float:right; width:400px; } +#solution.event .meta p{ position:absolute; right:80px; bottom:15px; width:auto; text-align:right; padding:0; } +.event .meta ul, .event .meta ul li{ margin:0; padding:0; list-style-type:none; } +.event .meta ul{ position:absolute; bottom:15px; right:0; } +.event .meta ul li{ float:left; margin-right:10px; width:24px; height:24px; } +.event .meta ul li a{ display:block; width:24px; height:24px; text-indent:-9999px; background-repeat:no-repeat; background-position:top left; } +.event .meta ul li.event_follow_rss a{ background-image:url(/common/img/icons/event_rss.jpg); } +.event .meta ul li.event_follow_calendar a{ background-image:url(/common/img/icons/event_calendar.jpg); } + +.eventb .banner_left{ width:295px; height:160px; background:#333; float:left; padding:30px; } +.eventb .banner_left h3{ color:#999; font-size:23px; line-height:25px; } +.eventb .banner_left h3 strong{ color:#7ac142; font-weight:normal; } +.eventb .banner_right{ width:623px; height:220px; float:left; } +.eventb h4{ color:#439539; font-size:25px; border:none; padding-bottom:15px; font-weight:300 } +.eventb .col_left{ border-top:1px solid #439539; padding-top:15px; } +.eventb .col_right{ border-top:1px solid #000; padding-top:15px; } +.eventb #content .col_left p.title{ font-size:19px; margin:0; padding:0 0 10px 0; color:#333; } +.eventb #content .col_left p.title strong{ color:#439539; font-weight:normal; } +.eventb #content .col_left hr{ background:#e4e5e6; } +.eventb #content .col_left p.register_now{ padding-bottom:0; } +.eventb #content .col_left p.register_now a{ text-decoration:none; } +.eventb #content .col_left p.register_now a:hover{ text-decoration:underline; } +.eventb .col_right{ border:none; padding-top:0; } +.eventb .col_right h4{ font-size:16px; font-weight:300; } +.eventb #content .col_right #events_ondemand a{ display:block; text-decoration:none; } + +/* Support +----------------------------------- */ +#support .feature h1 { color:#fff; font-size: 28px; font-weight: 300; } +#support .feature .wrap { position:relative; } +#support .feature li a{ color:#ccc; } +#support .feature li.active a, #support .feature #product_nav li a:hover{ color:#7ac142; } +#support .feature_main .links{ border-bottom:1px solid #7ac142; } +#support .feature{ background-image:url(/common/img/black_dotted_bg.png); background-color:#323232; } +#support .feature .headline{ float:none; width:auto; padding:50px 0 30px 0; font-size:29px; line-height:31px; color:#7ac142; min-height:0; } +#support .feature p{ color:#fff; padding-bottom:60px; width:650px; } +#support #content { margin-top:15px; } + +/* Downloads +----------------------------------- */ +#downloads h1{ font-size:28px; color:#439239; line-height:32px; font-weight:300; border-bottom:1px solid #439239; padding-bottom:7px; /*padding-right:200px;*/ margin-bottom:60px; } +#downloads .dl_heading, #training .training_heading{ margin-top:50px; font-size:18px; color:#333; font-weight:400; } +#training .training_heading{ font-size:28px; margin:0; padding:0 0 20px 0; font-weight:400; border:0; } +#downloads .product_list, #downloads .product_list li, #training .product_list, #training .product_list li{ margin:0; padding:0; list-style-type:none; } +#downloads .product_list, #training .product_list{ width:520px; } +#downloads .product_list li, #training .product_list li{ width:139px; float:left; margin:0 27px 32px 0; } +#downloads .product_list li a, #training .product_list li a{ text-decoration:none; display:block; font-size:16px; color:#439539; padding-top:85px; background:url(http://dummyimage.com/72x72) top left no-repeat; } + +/* Training +----------------------------------- */ +.training_index h1{ font-size:28px; color:#439239; line-height:32px; font-weight:300; margin-bottom:70px; } +.training_index #content h3{ font-size:15px; font-weight:400; color:#333; border-top:1px solid #333; padding:18px 0; margin-top:50px; } + +/* Company +----------------------------------- */ +#company .links{ border:none; } +#company .feature_company{ background:url(/common/img/gray_dotted_nofade.png) top left repeat; margin-top:15px; } +#company h3{ color:#439539; font-size:24px; line-height:26px; } +#company .feature_company h3{ width:700px; padding-bottom:43px; } +#company #content{ background:none; } + +#company .feature_company ul, #company .feature_company ul li{ margin:0; padding:0; list-style-type:none; } +#company .feature_company ul li{ float:left; } +#company .feature_company ul li a{ display:block; padding:8px 12px; color:#439539; text-decoration:none; } +/*#company .feature_company ul li:first-child a{ padding-left:0; }*/ +#company .feature_company ul li a:hover{ text-decoration:underline; } +#company .feature_company ul li.active{ background:#fff; } +#company .feature_company ul li.active a{ color:#333; } +#company .feature_company ul li.active a:hover{ text-decoration:none; } + +#company table tr td{ vertical-align:middle; } +#company table tr td:first-child{ padding-right:32px; } + +#company .section_title{ margin-top:50px; padding:32px 0 50px 0; border-top:1px solid #e0e0e0; font-size:27px; color:#439539; } +#company .content_left > .section_title:first-child{ margin-top:0; } +#company .bio_image{ float:right; margin:0 0 20px 20px; } +#company .suse_exec{ clear:both; padding-top:65px; } +#company .content_right ul.callout_links{ padding-bottom:20px; } + +#company.press h1{ margin-bottom:20px; } +#company.press h1 + p{ margin-bottom:20px; } +#company.press h4{ border:none; padding-top:0; } +#company.press .flyspec { font-size:11px; } + +.package_index .table_text tbody td.sub{ padding-left:25px; } +.package_index .table_text tbody td.title{ color:#333 } + +#content.contacts_offices .content_left select{ float:right; font-size:12px; margin-top:8px; } +#content.contacts_offices h3{ margin-bottom:40px; } +#content.contacts_offices .col_one_left{ width:182px; float:left; margin-right:20px; } +#content.contacts_offices .third{ float:left; width:165px; margin-right:40px; padding-top:20px; } +#content.contacts_offices .third td{ font-size:12px; color:#4b4b4b; } +#content.contacts_offices .last{ margin-right:0px; } +#content.contacts_offices .content_left h4{ font-family:"omnes-pro-1", Helvetica, Arial, sans-serif; font-size:18px; line-height:19px; font-weight:300; color:#333; text-transform:none; border:none; padding:0; } +#content.contacts_offices .col_one_right{ width:500px; float:left; } +#content.contacts_offices .col_one_right p{ padding:0 0 15px 0; } +#content.contacts_offices .col_one_right p:last-child{ padding-bottom:0; } +#content.contacts_offices table tr td:first-child{ padding:0; } +#content.contacts_offices hr{ margin:2em 0; } + + +/* Documentation +----------------------------------- */ +#documentation .prodlist a{ color:#439539; } + +/* Downloads +----------------------------------- */ +#downloads #content{ margin-top:0; } +#downloads h2{ font-size:28px; color:#333; line-height:30px; padding-bottom:32px; font-weight:400; width:600px; } +#downloads #content p a{ text-decoration:none; } +#downloads #content p a:hover{ text-decoration:underline; } + +/* Community +----------------------------------- */ +#community h1{ padding-bottom:8px; border-bottom:1px solid #439539; margin-bottom:35px; font-size:28px; font-weight:300; line-height:32px; color:#439539; } +#community h2{ clear:both; padding:9px 10px 8px 10px; margin:0 0 36px 0; text-transform:uppercase; color:#fff; font-size:14px; background:#8AC33C; line-height:100%; border:none; font-weight:400; } +#community h3{ font-size:14px; line-height:110%; font-weight:500; color:#000; padding:23px 40px 10px 0; background:-repeat:no-repeat; background:url(/common/img/social/icon_generic.png) top left no-repeat; } +#community h3 a{ color:#333; text-decoration:none; } +#community p.desc{ margin-bottom:34px; font-weight:400; color:#333; font-size:16px; width:700px; } +#community #content p{ padding-bottom:0; } +#community #content hr{ margin:36px 0; } +#community #content .callout_links{ padding-top:20px; } + +#community .contentfilter { border-top:1px solid #F0F0F0; border-bottom:1px solid #F0F0F0; } +#community .contentfilter ul { height:30px; line-height:30px; list-style-type:none; text-align:left; margin:0; padding:1px 0 0 0; } +#community .contentfilter li { float:left; font-size:12px; text-indent:4px; padding-right:32px; } +#community .contentfilter li a { color:#439539; text-decoration:none; background:url(/common/img/bullets/subnav.png) 0px 4px no-repeat; padding-left:15px; } +#community .contentfilter li.selected { background:#00AEEF url(/common/img/filter_selected_bg.png) no-repeat top right; } + +#community #communities { margin:0; padding:32px 0 0 0; width:978px; overflow:hidden; } +#community .communitycategory { overflow:hidden; width:1020px; border-top:2px solid #fff; padding:0 0 30px 0; clear:both; background-color:#fff; } +#community .divider { clear:both; padding-top:34px; border-top:1px solid #fff; } + +#community .communityfeed { position:relative; width:338px; float:left; padding-bottom:20px; } +#community .communityfeed p { margin:0; padding:0 40px 0 0; font-size:11px; } +#community .communityfeed ul { list-style-type:none; margin:16px 40px 0 0; padding:16px 0 0 0; border-top:1px solid #F0F0F0; } +#community .communityfeed ul li { margin:0; padding:0 0 16px 0; font-size:11px; line-height:120%; background-image:none; } +#community .communityfeed ul li strong { font-weight:normal; display:block; } +#community .communityfeed ul li a { text-decoration:none; } +#community .communityfeed ul li a:hover { text-decoration:underline; color:#439539; } +#community p.feedaction { clear:left; padding:6px 0 0 0; margin:0 40px 0 0; border-top:1px solid #F0F0F0; } +#community p.feedaction a strong { font-weight:normal; color:#439539; } +#community p.feedaction a { text-decoration:none; color:#333; } +#community p.feedrss { clear:left; margin:0; padding:0; position:relative; left:274px; top:-14px; } + +#community #content .callout_links { padding-top:0px; } +#community .communityfeed ul.callout_links { border-top:none; padding-top:0px; padding-bottom:0px; } +#community .communityfeed ul.callout_links li { padding-bottom:0px; border:none; } + +/* Landing page +----------------------------------- */ +#landing_page #landing_page_banner{ padding:63px 0; background:url(http://dummyimage.com/250x150) center right no-repeat; border-bottom:1px solid #439539; margin-bottom:50px; } +#landing_page #content #landing_page_banner h1{ border:none; margin:0; padding:0 275px 0 0; } +#landing_page #content #landing_page_banner h1 strong{ color:#333; font-weight:300; } +#landing_page #content h2{ font-weight:500; margin-top:32px; border-top:1px solid #e0e0e0; padding:18px 0; font-size:15px; } +#landing_page #content table td{ padding-right:12px; } + +/* Share/print +----------------------------------- */ +.share{ margin-bottom:10px; } +#content .post p.social{padding:10px 0 0 0; height: 20px; } +#content a.social_btns{display:block; float:left; padding: 0 6px; font-size: 10px; line-height: 18px; border: 1px solid #e6e6e6; background: #eaeaea url(/common/img/social/social_btn_bg.gif) repeat-x left top; margin-right: 7px; text-decoration:none; color:#888; } +#content a.social_btns img{padding-left: 5px; border-left: 1px solid #e6e6e6; margin: 4px 0 0 0; } +#content a.social_btns:hover{text-decoration:none !important;} +#content a.share_btn{height: 18px; } +#content a.share_btn img{padding-left: 5px; border-left: 0 none; margin: 3px 0 -3px 0; } + +#content .post-share-links{display: none; position: relative; height: 0;} +#content .post-share-links ul{position:absolute; top: -88px; left: 0; z-index: 30001; display: block; height:94px; width:99px; background: transparent url(/common/img/social/share_popup_black_bg.png) no-repeat left top; margin: 0; padding: 8px;} +#content .post-share-links ul li{line-height: 19px; height: 19px; margin: 0 0 10px 0; background: 0; padding: 0; list-style-type:none; } +#content .post-share-links ul li a{font-weight: bold; font-size: 11px; font-family: arial, helvetica, sans-serif; background: transparent no-repeat left top; padding: 5px 0 5px 30px; color: #cccccc; text-decoration:none; } +#content .post-share-links ul li a:hover{text-decoration: underline; } +#content .post-share-links ul li a.post-share-link-facebook{background-image: url(/common/img/social/social_popup_facebook_icon-1.png);} +#content .post-share-links ul li a.post-share-link-twitter{background-image: url(/common/img/social/social_popup_twitter_icon-1.png);} +#content .post-share-links ul li a.post-share-link-email{background-image: url(/common/img/social/social_popup_email_icon-1.png);} + + +/* RAC/lead gen form +----------------------------------- */ +.content_right img + #requestcall{ padding-top:15px; } + +#content #requestcall #racError, #overlay #requestcall #racError{ padding-bottom:10px; } +#content #requestcall #racError p, #content #requestcall #racError ul, #overlay #requestcall #racError p, #overlay #requestcall #racError ul{ padding:5px; } +#content #requestcall #racError p, #content #requestcall #racError li, #overlay #requestcall #racError p, #overlay #requestcall #racError li{ color:#C00 !important; margin:0; font-size:11px; } +#content #requestcall #racError strong, #overlay #requestcall #racError strong{ color:#C00 !important;} +#content #requestcall #racError p, #overlay #requestcall #racError p{ margin:0; padding:8px 0 2px 0; } +#content #requestcall #racError #racErrorMsgs p, #overlay #requestcall #racError #racErrorMsgs p{ padding-left:18px; background:transparent url(http://www.novell.com/common/img/icons/missing_field.png) no-repeat 0px 8px; } +#form_content div.form-error input, #form_content div.form-error textarea, #form_content div.form-error select,.form_content div.form-error input, .form_content div.form-error textarea, .form_content div.form-error select{ border:2px solid #ED1D25; } +#form_content div.form-error select{ height:22px; } +#content #requestcall .title{ font-size:15px; color:#439539; font-weight:400; border-top:1px solid #439539; padding:15px 0; line-height:17px; } +#requestcall .phonecall{ font:11px Arial, Helvetica, sans-serif; color:#999; line-height:12px; } +#requestcall #required_note{ padding-bottom:5px; text-align:right; font-size:11px; } +#requestcall #required_note, #requestcall .req{ color:#CC0000; } +#form_content label, .form_content label{ /*margin-right:12px;*/ text-align:right; font-size:11px; color:#595959; padding:0; } +#form_content input, .form_content input{ width:210px; padding:3px 5px; font-size:11px; color:#2c3333; } +#form_content select, .form_content select{ width:221px; font-size:11px; padding:0; color:#333; } +#form_content textarea, .form_content textarea{ border:none; padding:5px; width:210px; font:11px Arial; color:#2C3333; line-height:12px; height:13px; } +#form_content input, #form_content textarea, .form_content input, .form_content textarea{ border:1px solid #e4e4e4; background-image: -webkit-gradient(linear, left bottom, left top, color-stop(0.47, rgb(253,253,253)), color-stop(0.82, rgb(238,238,238))); background-image: -moz-linear-gradient(center bottom, rgb(253,253,253) 47%, rgb(238,238,238) 82%); } +#form_content input:focus, #form_content textarea:focus, .form_content input:focus, .form_content textarea:focus{ background-image: -webkit-gradient(linear, left bottom, left top, color-stop(0.47, rgb(234,242,246)), color-stop(0.83, rgb(200,207,209))); background-image: -moz-linear-gradient(center bottom, rgb(234,242,246) 47%, rgb(200,207,209) 83%); border:1px solid #b0b0b0; } +.content_right #form_content{ width:222px; overflow:hidden; } +.content_right #form_content fieldset{ width:240px; } +#form_content fieldset div. .form_content fieldset div{ clear:both; padding:0 0 5px 0; } +#form_content #disclaimer{ font-size:11px; line-height:11px; padding:16px 0; color:#999; clear:both; } +#form_content #disclaimer a{ color:#999; text-decoration:underline; } +#form_content #disclaimer a:hover{ color:#000; } +#form_content div span.instructions. .form_content div span.instructions{ font-size:11px; color:#C5312C; display:none; } +.form_submit{ height:50px; display:none; } +.form_submit p{ font-size:12px; float:right; } +.form_submit p div{ width:1px !important; height:auto; } +.secure .form_submit p{ padding-left:30px; background:url(http://novell.com/common/img/forms/form_secure.png) 0px 2px no-repeat; } +.form_submit p a{ color:#fff !important; text-decoration:none !important; background:url(/common/img/green_dotted_bg.png) top left repeat; display:block; padding:4px 12px 5px 12px; } +.form_submit p a:hover{ text-decoration:none !important; color:#fff; background-position:bottom right; } +#form_content .form_submit_hide, .form_content .form_submit_hide, #form_content .form_submit_hide input, .form_content .form_submit_hide input{ margin:0; padding:0; border:none; height: 1px; width: 1px; position: absolute; z-index: -100; } + +#form_content input.validation-failed, .form_content input.validation-failed{ border:2px solid #ED1D25; } +#form_content div.input_advice, .form_content div.input_advice{ font-size:11px; font-weight:bold; padding-top:5px; color:#ED1D25; } + +#form_content div.half, #form_content div.extra-fields{ float:left; width:104px; clear:none; margin-right:12px; } +#form_content div.half input, #form_content div.extra-fields input{ width:93px; } +#form_content div.half select{ width:105px; height:20px; } +#form_content div.last{ margin-right:0 !important; } + +.content_left #form_content div#requestcall_email{ float:left; clear:none; margin-right:12px; } +.content_left #requestcall #form_wrap{ padding:20px; background:#eee; margin-bottom:20px; } +/*.content_left #requestcall form{ padding:20px; background:#eee; }*/ +.content_left #requestcall form fieldset{ width:550px; } +.content_left #requestcall form fieldset > div{ width:235px !important; padding-top:10px; } +.content_left #requestcall #form_content label{ text-align:left; display:block; } +.content_left #requestcall #form_content input{ width:222px; background:#fff; } +.content_left #requestcall #form_content select{ width:233px; background:#fff; margin-bottom:4px; } +.content_left #requestcall #form_content textarea{ width:470px; background:#fff; height:23px; } +.content_left #requestcall #form_content #disclaimer{ width:480px; } +.content_left #requestcall .form_submit{ height:24px; } +#content .content_left #requestcall .title{ color:#333; border:none; padding-top:30px; font-size:20px; font-weight:400; } +.content_left #form_content div.last{ margin-right:12px !important; } + +/* MST3k overrides +-------------------------------------------------- */ +#mst3k_address1, #mst3k_postalCode, #mst3k_state{ display:none; } +#mst3k_address1, #mst3k_postalCode{ clear:left; } +#MST_form .half, #MST_form .full{ margin-top:6px; } +#MST_form .full{ clear:both; } + +/* Landing Pages +----------------------------------- */ +.landing_page .feature{ padding:0; } +.landing_page .feature_main .wrap{ background:url(/home/img/banners/zenterprise.png) right bottom no-repeat; padding:80px 0; } +.landing_page .feature_main h1{ margin:0; padding:0; border:none; font-size:28px; line-height:28px; color:#fff; width:500px; } +.landing_page_gray .feature_main{ background-image:url(/common/img/gray_dotted_nofade.png); } +.landing_page_gray .feature_main h1{ color:#439539; } +.landing_page_gray #content{ background:none; } + +.landing_page #content .content_left h1{ border-top:0; padding:0; margin-bottom:40px; } +.landing_page #content .content_left blockquote{ font-style:normal; margin-bottom:20px; } +.landing_page #content .content_left ol, .landing_page #content .content_left ul{ color:#439539 !important; } +.landing_page #content .content_left ol li, .landing_page #content .content_left ul li{ color:inherit; margin-bottom:3px; } +.landing_page #content .content_left ol li p, .landing_page #content .content_left ul li p{ color:#5F5F5F; margin:0; padding:0; } +.landing_page #content .content_left p.small{ font-size:11px; color:#999; } +.landing_page #content .content_left .trio_list ul li{ width:190px; margin-right:35px !important; } +.landing_page #content .content_left .trio_list ul li.third{ margin-right:0px !important; } +.landing_page #content .content_left .trio_list p.title{ font-size:17px; line-height:17px; padding:32px 0; margin:15px 0; border-top:1px solid #439593; border-bottom:1px solid #eee; } + +.landing_page #content h4{ border-top:1px solid #333; padding:18px 0; font-size:15px; } +.landing_page #content .content_right blockquote{ font-style:normal; border-top:1px solid #333; border-bottom:1px solid #333; margin:0; } +.landing_page #content .content_right blockquote strong, .landing_page #content .content_right blockquote span{ width:100%; text-align:right; } +.landing_page #content .content_right #customers li{ float:none; margin-bottom:15px; clear:left; } +.landing_page #content .content_right #customers li img{ width:60px; float:left; margin-right:20px; } +.landing_page #content .content_right #customers p{ border:none; padding:0 0 0 80px; } + +#content #follow ul, #content #follow ul li{ margin:0; padding:0; list-style-type:none; } +#content #follow ul li{ width:24px; height:24px; margin:0 10px 10px 0; float:left; } +#content #follow li a{ width:24px; height:24px; display:block; text-indent:-9999px; background-position:top left; background-repeat:no-repeat; } +#content #follow li a:hover{ background-position:bottom left; } +#follow li#sf_cool a{ background-image:url(http://www.novell.com/common/img/follow/cool.jpg); } +#follow li#sf_email a{ background-image:url(http://www.novell.com/common/img/follow/email.jpg); } +#follow li#sf_fb a{ background-image:url(http://www.novell.com/common/img/follow/fb.jpg); } +#follow li#sf_forum a{ background-image:url(http://www.novell.com/common/img/follow/forum.jpg); } +#follow li#sf_quote a{ background-image:url(http://www.novell.com/common/img/follow/quote.jpg); } +#follow li#sf_rss a{ background-image:url(http://www.novell.com/common/img/follow/rss.jpg); } +#follow li#sf_twitter a{ background-image:url(http://www.novell.com/common/img/follow/twitter.jpg); } +#follow li#sf_url a{ background-image:url(http://www.novell.com/common/img/follow/url.jpg); } + +.landing_noleak #form_wrap #form_content div{ clear:both; padding-top:5px; } +.landing_noleak #form_wrap #form_content label{ float:left; width:100px; padding-top:3px; } +.landing_noleak #form_wrap #form_content input, .landing_noleak #form_wrap #form_content select{ float:left; width:150px; } +.landing_noleak #form_wrap #form_content select{ width:160px; padding:2px 0; } +.landing_noleak #form_wrap #form_content div.questions{ clear:both; padding-top:15px; } +.landing_noleak #form_wrap #form_content div.questions p{ padding-bottom:5px; } +.landing_noleak #form_wrap #form_content div.questions label{ float:none; width:auto; padding:0; display:block; text-align:left; } +.landing_noleak #form_wrap #form_content div.questions input{ float:none; width:249px; } +.landing_noleak #form_wrap #form_content div.questions select{ float:none; width:275px; } + +.landing_noleak .content_left{ width:608px; margin-right:45px; } +.landing_noleak #content .content_left .trio_list ul li{ margin-right:19px !important; } +.landing_noleak .content_right{ width:325px; } +.landing_noleak .content_right h2.title{ background:#333; padding:32px 22px; color:#7ac142; border-bottom:1px solid #000; margin:0; font-size:23px; line-height:22px; font-weight:100; } +.landing_noleak #form_wrap{ background:#333; border-top:1px solid #3e3e3e; padding:22px; } +.landing_noleak #form_content{ width:281px; } +.landing_noleak #form_content fieldset{ width:281px; } +.landing_noleak #form_content fieldset input{ width:269px; } +.landing_noleak #form_content fieldset div{ padding-bottom:10px; } +.landing_noleak #form_wrap #form_content #eloqua_form label, .landing_noleak #form_wrap #form_content #eloqua_form input, .landing_noleak #form_wrap #form_content #eloqua_form select, .landing_noleak #form_wrap #form_content #MST_form label, .landing_noleak #form_wrap #form_content #MST_form input, .landing_noleak #form_wrap #form_content #MST_form select{ float:none; } +.landing_noleak #form_wrap #form_content #eloqua_form input, .landing_noleak #form_wrap #form_content #MST_form input{ width:269px; } +.landing_noleak #form_wrap #form_content fieldset div.half, .landing_page #form_wrap #form_content fieldset div.extra-fields{ width:134px; clear:none; } +.landing_noleak #form_wrap #form_content fieldset div.half label, .landing_page #form_wrap #form_content fieldset div.extra-fields label{ float:none; width:auto; padding:0; } +.landing_noleak #form_wrap #form_content #eloqua_form fieldset div.half input, .landing_page #form_wrap #form_content #eloqua_form fieldset div.extra-fields input, .landing_noleak #form_wrap #form_content #MST_form fieldset div.half input, .landing_page #form_wrap #form_content #MST_form fieldset div.extra-fields input{ width:126px; } +.landing_noleak .form_submit{ height:26px; } +.landing_noleak #MST_form .input_advice{ padding-bottom:0px; } +.landing_noleak #content .form_asset_desc p{ text-transform:uppercase; font-size:11px; color:#fff; padding:15px 0 30px 0; } +.landing_noleak #content .form_asset_desc p strong{ display:block; font-weight:bold; } +.landing_noleak #content label{ color:#999; } +.landing_noleak #content #required_note{ text-align:right; font-size:11px; color:#999; margin:0; padding-bottom:5px; } +.landing_noleak #content .req{ color:#fff; } + + +#rac_preview{ padding:15px 0; border-top:1px solid #439539; /*border-bottom:1px solid #439539;*/ } +#rac_preview p{ margin:0; padding:0; color:#439539; } +#rac_preview .button a{ background:#439539 url(/common/img/button_bg.png) bottom left no-repeat; padding:0 10px 0 0; margin-top:12px; display:block; text-decoration:none; } +#rac_preview .button a:hover{ text-decoration:none; background-position:top left; } +#rac_preview .button_rac a{ padding-right:12px; } +#rac_preview .button a span{ font-size:15px; color:#fff; padding:10px; display:block; } +#rac_preview .button_rac a span{ background:url(/common/img/phone.png) center right no-repeat; } +#rac_preview .button_chat{ display:none; } /* disable by default. EMEA countries will have it enabled via JS */ +#rac_preview .button_chat a span{ background:url(/common/img/chat_bubble.png) center right no-repeat; } +.ie6 .career #meta_wrap{ height:164; } +.ie6 .career .feature .wrap{ padding:80px 0 0 0; } +.ie6 .career #content{ clear:both; } +.ie6 #rac_preview p.button{ height:30px; } +#rac_preview.rac_button_embedded{ padding:0 0 15px 0; border-top:0; } +#rac_preview.rac_button_embedded a{ margin-top:0; } + + +.landing_ty_asset .content_left, .landing_ty_asset .content_right{ width:43% } +.landing_ty_asset .asset{ background:#333; padding:22px; border-bottom:1px solid #000; border-top:1px solid #3e3e3e; } +.landing_ty_asset #content .asset p{ color:#fff; text-transform:uppercase; font-size:11px; padding:0; } +.landing_ty_asset #content .asset p strong{ display:block; } +.landing_ty_asset #content .asset p.download{ padding-top:15px; } +.landing_ty_asset #content .asset p.download a{ background:url(/common/img/green_dotted_bg.png) top left repeat; text-transform:none; padding:4px 12px 5px; text-decoration:none !important; color:#fff; display:inline-block; } + + +/* Sidebar content +----------------------------------- */ +.module{ padding-bottom:36px; } + +#content .rac_sublinks, #content .rac_sublinks li{ margin:0; padding:0; list-style-type:none; } +#content .rac_sublinks li{ font-size:14px; padding:6px 0 3px 0; border-top:1px solid #439539; } +#content .rac_sublinks li.last-child{ border-bottom:1px solid #439539; } +#content .rac_sublinks li a{ color:#439539; text-decoration:none; display:block; } +#content .rac_sublinks li a:hover{ text-decoration:underline; } + +#industry_experts p{ font-size:13px; line-height:16px; } +#industry_experts p a{ color:#646464; text-decoration:none; } +#industry_experts p strong{ font-weight:500; color:#439539; display:block; } +#industry_experts p.last-child{ padding-bottom:0; } +#industry_experts p a:hover{ text-decoration:underline; } + +#news_events ul, #news_events ul li, #follow_social ul, #follow_social ul li, #alliance_partners ul, #alliance_partners ul li{ margin:0; padding:0; list-style-type:none; } +#news_events ul li{ font-size:13px; padding:10px 0; color:#646464; line-height:16px; } +#news_events ul li a{ color:#666; text-decoration:none; } +#news_events ul li a:hover{ text-decoration:underline; } +#news_events ul li span{ display:block; color:#999; } + +#follow_social ul li{ width:24px; height:24px; float:left; margin-right:10px; } +#follow_social ul li a{ display:block; background:url(http://dummyimage.com/24x48.jpg) top left no-repeat; text-indent:-9999px; width:24px; height:24px; } +#follow_social ul li a:hover{ background-position:bottom left; } +#follow_social ul li.follow_fb a{ background-image:url(/common/img/social/facebook_24x24.png); } +#follow_social ul li.follow_cs a{ background-image:url(/common/img/social/cool_24x24.png); } +#follow_social ul li.follow_forum a{ background-image:url(/common/img/social/forums_24x24.png); } +#follow_social ul li.follow_blog a{ background-image:url(/common/img/social/blog_24x24.png); } +#follow_social ul li.follow_newsletter a{ background-image:url(/common/img/social/newsletter_24x24.png); } +#follow_social ul li.follow_rss a{ background-image:url(/common/img/social/rss_24x24.png); } +#follow_social ul li.follow_site a{ background-image:url(/common/img/social/rss_site.png); } +#follow_social ul li.follow_twitter a{ background-image:url(/common/img/social/rss_twitter.png); } + +#alliance_partners ul li{ width:74px; float:left; margin-bottom:10px; text-align:center; } +#alliance_partners ul li a{ display:block; width:80px; height:44px; background-repeat:no-repeat; background-position:top center; text-indent:-9999px; } +#alliance_partners ul li a:hover{ box-shadow: 0 0 10px #439539; -webkit-box-shadow: 0 0 10px #439539; -moz-box-shadow: 0 0 10px #439539; } + +#alliance_partners ul li#amd a{ background-image:url(/common/img/alliance_partners/amd.png); } +#alliance_partners ul li#broadcom a{ background-image:url(/common/img/alliance_partners/broadcom.png); } +#alliance_partners ul li#brocade a{ background-image:url(/common/img/alliance_partners/brocade.png); } +#alliance_partners ul li#emulex a{ background-image:url(/common/img/alliance_partners/emulex.png); } +#alliance_partners ul li#fujitsu a{ background-image:url(/common/img/alliance_partners/fujitsu.png); } +#alliance_partners ul li#hp a{ background-image:url(/common/img/alliance_partners/hp.png); } +#alliance_partners ul li#ibm a{ background-image:url(/common/img/alliance_partners/ibm.png); } +#alliance_partners ul li#intel a{ background-image:url(/common/img/alliance_partners/intel.png); } +#alliance_partners ul li#lsi a{ background-image:url(/common/img/alliance_partners/lsi.png); } +#alliance_partners ul li#microsoft a{ background-image:url(/common/img/alliance_partners/microsoft.png); } +#alliance_partners ul li#nvidia a{ background-image:url(/common/img/alliance_partners/nvidia.png); } +#alliance_partners ul li#oracle a{ background-image:url(/common/img/alliance_partners/oracle.png); } +#alliance_partners ul li#qlogic a{ background-image:url(/common/img/alliance_partners/qlogic.png); } +#alliance_partners ul li#sap a{ background-image:url(/common/img/alliance_partners/sap.png); } +#alliance_partners ul li#symantec a{ background-image:url(/common/img/alliance_partners/symantec.png); } +#alliance_partners ul li#vmware a{ background-image:url(/common/img/alliance_partners/vmware.png); } +#alliance_partners ul li#dell a{ background-image:url(/common/img/alliance_partners/dell.png); } + +#content .link_arrow{ margin:0; padding:15px 0 36px 0; } +#content .link_arrow a{ display:block; padding-left:21px; background:url(/common/img/link_arrow.png) top left no-repeat; color:#439239; text-decoration:none; } +#content .link_arrow a:hover{ text-decoration:underline; } +#content .content_left .link_arrow{ padding-top:0; } + +/* Careers +----------------------------------- */ +.career img.infographic{ width:966px; box-shadow: 0px 0px 15px #bbb; -moz-box-shadow: 0px 0px 15px #bbb; -webkit-box-shadow: 0px 0px 15px #bbb; border:6px solid white; margin-top:15px; } +.career .career_content{ width:700px; padding-top:10px; } +.career .suse_button{ float:right; padding-top:10px; } + +.career h3{ margin-bottom:60px; } + +.career_right p{ padding-top:10px !important; font-size:12px; } +.career_right h4{ clear:both; color:#439539; border-color:#439539; margin:8px 0; } +.career_right img{ display:block; padding:10px; background:#fff; box-shadow:0px 0px 5px #ccc; margin-bottom:5px; } +#content .jobs_title{ color:#666; font-family:"omnes-pro-1"; font-size:16px; text-align:center; } +.career_right .quotes{ margin-top:7px; } +.career_right blockquote{ margin:0; padding:15px 0 0 0; font-style:italic; font-size:12px; display:none; font-weight:normal; font-family:Arial, Helvetica, sans-serif; } +.career .content_left .suse_button{ float:none; } + +.career .career_num{ width:70px; height:93px; display:block; float:left; margin-right:5px; background-repeat:no-repeat; background-position:top left; text-indent:-9999px; } +.career .num_last{ margin-right:0; } +.career .num_0{ background:url(/company/careers/numbers/0.png); } +.career .num_1{ background:url(/company/careers/numbers/1.png); } +.career .num_2{ background:url(/company/careers/numbers/2.png); } +.career .num_3{ background:url(/company/careers/numbers/3.png); } +.career .num_4{ background:url(/company/careers/numbers/4.png); } +.career .num_5{ background:url(/company/careers/numbers/5.png); } +.career .num_6{ background:url(/company/careers/numbers/6.png); } +.career .num_7{ background:url(/company/careers/numbers/7.png); } +.career .num_8{ background:url(/company/careers/numbers/8.png); } +.career .num_9{ background:url(/company/careers/numbers/9.png); } + + +/* ISV Catalog +----------------------------------- */ +br.clear{ clear:both; } +#app_tier4 h1{ position:static; font-size:30px; color:#439539; font-weight:400; padding-top:30px; } +#app_tier4 #desc1{ font-size:20px; float:none; } +#app_tier4 #desc2{ color:#439539; font-size:19px; font-weight:normal; } +#app_tier4 #contentcontainer{ padding:0 !important; background:none; } +#app_tier4 #info_box #info_line1, #app_tier4 #info_box #info_line2, #app_tier4 #info_box #info_line3{ height:auto; } +#app_tier4 #contenthead{ height:auto; border:none; } +#app_tier4 #subcontenthead p{ font-weight:bold; font-size:18px; color:#439539; padding:0; } +#app_tier4 #subcontenthead p.sub{ font-weight:normal; font-size:15px; color:#333; } + +/* Footer +----------------------------------- */ +footer{ /*background:#E4E7E9;*/ padding:36px 0 62px 0; } +footer .col{ padding:0 16px; float:left; width:130px; } +footer h5{ font-size:15px; color:#439539; margin:26px 0 20px; font-weight:300; } +footer ul{ margin:0; padding:0; list-style-type:none; } +footer ul li{ border-bottom:1px solid #C6C6C6; font-size:11px; font-family:Helvetica, Arial, sans-serif; } +footer ul li:first-child{ border-top:1px solid #C6C6C6; } +footer ul li a{ color:#666; text-decoration:none; display:block; padding:2px 0; } +footer ul li a:hover{ color:#439339; } + +footer.product, footer.home{ background:#202020; padding-bottom:0; } +footer.product .wrap .col, footer.home .wrap .col{ border-top:1px solid #76ad2d; padding:17px 0 0 0; margin-right:32px; } +footer.product .wrap .col h5, footer.home .wrap .col h5{ margin:0 0 15px 0; color:#999; } +footer.product .wrap .col h5 a, footer.home .wrap .col h5 a{ color:#999; text-decoration:none; } +footer.product .wrap .col h5 a:hover, footer.home .wrap .col h5 a:hover{ color:#666; } +footer.product .wrap .col ul, footer.home .wrap .col ul{ padding-bottom:32px; } +footer.product .wrap .col ul li, footer.home .wrap .col ul li{ border-bottom:1px solid #2f2f2f; /*font-family:Omnes_Regular;*/ } +footer.product .wrap .col ul li:first-child, footer.home .wrap .col ul li:first-child{ border-top:1px solid #2f2f2f; } +footer.product .wrap .col ul li a, footer.home .wrap .col ul li a{ color:#76ad2d; padding:8px 2px 5px; } +footer.product .wrap .col ul li a:hover, footer.home .wrap .col ul li a:hover{ color:#5E9632; } +footer.product .subtitle{ font-size:11px; color:#fff; } + +footer.product .wrap .col:first-child, footer.home .wrap .col1{ width:222px; } +footer.product .wrap .col:first-child ul{ padding-top:22px; } +footer.product .wrap .col:first-child li{ border-bottom:1px solid #76ad2d; padding:2px 0; font-weight:500; } +footer.product .wrap .col:first-child li#footer_rac{ background:#76ad2d; } +footer.product .wrap .col:first-child li:first-child{ border-top:1px solid #76ad2d; } +footer.product .wrap .col:first-child li a{ color:#e3e4e5; font-size:13px; padding:2px 5px 2px 5px; } +footer.product .wrap .col:first-child li a:hover{ color:#fff; text-decoration:none; } +footer.product .wrap .col:first-child li#footer_rac a{ color:#202020; } +footer.product .wrap .col:first-child li#footer_rac a:hover{ color:#000; } + +footer.product .wrap .second-child{ width:304px; } +footer.product .wrap .third-child{ width:388px; margin-right:0; } + +footer.home .wrap .col{ float:left; margin-right:30px; } +footer.home .col1, footer.home .col5{ width:222px; } +footer.home .col2, footer.home .col3, footer.home .col4{ width:138px; } +footer.home .wrap .col1{ padding-top:0; border-top:none; } +footer.home .wrap .col5{ margin:0; } +footer.home p{ color:#999; padding-bottom:20px; } +footer.home .footer_title{ font-weight:100; color:#76AD2D; font-size:25px; padding-bottom:15px; } + +footer.home .footer_global{ padding:0; background:none; } +footer.home .footer_global p, footer.home .footer_global a{ color:#666 !important; } + +footer .footer_global{ background:#f2f2f2; padding:32px 0 28px; min-width:1018px; } +footer .footer_global p, footer .footer_global ul li{ float:left; color:#333; padding-right:32px; font-size:12px; } +footer .footer_global p{ font-weight:500; padding-top:2px; } +footer .footer_global p#suse_phone{ float:right; padding:0; } +footer .footer_global p#suse_phone a{ color:#333; text-decoration:none; } +footer .footer_global p#suse_phone a:hover{ text-decoration:underline; } +footer .footer_global li{ font-weight:400; border:none !important; } +footer .footer_global li a:hover{ text-decoration:underline; color:#76ad2d; } + +/* Typekit font events to eliminate FOUT on Firefox: http://blog.typekit.com/2010/10/29/font-events-controlling-the-fout/ +----------------------------------- */ +.wf-loading h1, +.wf-loading h1 strong, +.wf-loading h2, +.wf-loading h3, +.wf-loading h4, +.wf-loading h5, +/*.wf-loading header ul#nav li,*/ +/*.wf-loading .feature #product_nav li,*/ +.wf-loading .feature .headline, +.wf-loading .feature .headline strong, +.wf-loading .feature #cta_links #cta a, +.wf-loading #content .callout p, +.wf-loading #content .highlight p, +.wf-loading #content .callout p strong, +.wf-loading #content .sublinks li, +.wf-loading #content .sublinks li strong, +.wf-loading #content p.title, +.wf-loading #content .content_left .anchor_content strong, +.wf-loading #content .content_left .anchor_title, +.wf-loading #content .content_left .anchor_title span, +.wf-loading blockquote, +.wf-loading blockquote span, +.wf-loading #content .product_list li p.title, +.wf-loading #content .product_list li a, +.wf-loading #content .subtitle, +.wf-loading #content .greenbox p.number, +.wf-loading #content .greenbox p.text, +.wf-loading #content .col_small blockquote, +.wf-loading .table_comparison tbody td, +.wf-loading .version_comparison tbody td span, +.wf-loading #content .table_header, +.wf-loading .support_comparison thead th span, +.wf-loading .support_comparison .buy a, +.wf-loading #content .box p.box_title, +.wf-loading #community p.desc, +.wf-loading #content #requestcall .title, +.wf-loading footer.product .wrap .col:first-child li, +.wf-loading .col_highlight_one p, +.wf-loading header ul#nav .nav_subheading, +.wf-loading #company .section_title, +.wf-loading .offer a span, +.wf-loading footer.home .footer_title, +.wf-loading #training .training_heading, +.wf-loading .promo_sidebar a strong{ visibility:hidden; } + +/* Typekit font customizations +----------------------------------- */ +/* .tk-omnes-pro is the default class which enables this on any element to which the class is applied */ +h1, +h1 strong, +h2, +h3, +h4, +h5, +/*header ul#nav li,*/ +/*.feature #product_nav li,*/ +.feature .headline, +.feature .headline strong, +.feature #cta_links #cta a, +#content .callout p, +#content .highlight p, +#content .sublinks li, +#content .sublinks li strong, +#content p.title, +#content .content_left .anchor_content strong, +#content .content_left .anchor_title, +#content .content_left .anchor_title span, +blockquote, +blockquote span, +#content .product_list li p.title, +#content .product_list li a, +#content .subtitle, +#content .greenbox p.number, +#content .greenbox p.text, +#content .col_small blockquote, +.table_comparison tbody td, +.version_comparison tbody td span, +#content .table_header, +.support_comparison thead th span, +.support_comparison .buy a, +#content .box p.box_title, +#community p.desc, +#content #requestcall .title, +footer.product .wrap .col:first-child li, +.col_highlight_one p, +.col_highlight_one p strong, +header ul#nav .nav_subheading, +#company .section_title, +.offer a span, +footer.home .footer_title, +#training .training_heading, +.promo_sidebar a strong{ font-family: "omnes-pro-1", "omnes-pro-2", Helvetica, Arial, sans-serif; } + +/* Japanese/Chinese overrides +----------------------------------- */ +.ja-jp .feature .headline, .zh-cn .feature .headline{ font-size:31px; line-height:38px; } +.ja-jp .feature #cta_links #cta a, .zh-cn .feature #cta_links #cta a{ line-height:32px; } +.ja-jp #content .callout p, .zh-cn #content .callout p{ line-height:26px; } +.ja-jp #trial_content h2, .ja-jp #content p, .ja-jp footer p, .ja-jp #form_content #disclaimer, .ja-jp #content .sublinks li, .zh-cn #content p, .zh-cn #form_content #disclaimer, .zh-cn #content .sublinks li{ line-height:130%; } +.ja-jp #content .content_left .anchor_content li, .zh-cn #content .content_left .anchor_content li{ line-height:18px; } +/* Need to specifically override elements that were targeted for Omnes font customization */ +html body.ja-jp, +html body.ja-jp #container, +.ja-jp h1, +.ja-jp h1 strong, +.ja-jp h2, +.ja-jp h3, +.ja-jp h4, +.ja-jp h5, +.ja-jp .feature .headline, +.ja-jp .feature .headline strong, +.ja-jp .feature #cta_links #cta a, +.ja-jp #content .callout p, +.ja-jp #content .highlight p, +.ja-jp #content .sublinks li, +.ja-jp #content .sublinks li strong, +.ja-jp #content p.title, +.ja-jp #content .content_left .anchor_content strong, +.ja-jp #content .content_left .anchor_title, +.ja-jp #content .content_left .anchor_title span, +.ja-jp blockquote, +.ja-jp blockquote span, +.ja-jp #content .product_list li p.title, +.ja-jp #content .product_list li a, +.ja-jp #content .subtitle, +.ja-jp #content .greenbox p.number, +.ja-jp #content .greenbox p.text, +.ja-jp #content .col_small blockquote, +.ja-jp .table_comparison tbody td, +.ja-jp .version_comparison tbody td span, +.ja-jp #content .table_header, +.ja-jp .support_comparison thead th span, +.ja-jp .support_comparison .buy a, +.ja-jp #content .box p.box_title, +.ja-jp #community p.desc, +.ja-jp #content #requestcall .title, +.ja-jp footer.product .wrap .col:first-child li, +.ja-jp .col_highlight_one p, +.ja-jp .col_highlight_one p strong, +.ja-jp header ul#nav .nav_subheading, +.ja-jp #company .section_title, +.ja-jp .offer a span, +.ja-jp footer.home .footer_title, +.ja-jp #training .training_heading, +.ja-jp .promo_sidebar a strong, +.ja-jp header ul#nav li, +.ja-jp footer ul li{ font-family:"メイリオ","Meiryo","ヒラギノ角ゴ Pro W3","Hiragino Kaku Gothic Pro","MS Pゴシック","arial","sans-serif" !important } + + +.hu-hu header ul#nav li#nav_solutions{ width:115px; } +.hu-hu header ul#nav li#nav_products{ width:210px; } +.hu-hu header ul#nav li#nav_support{ width:140px; } +.hu-hu header ul#nav li#nav_partners{ width:100px; } +.hu-hu header ul#nav li#nav_community{ width:100px; } +.hu-hu header ul#nav li#nav_dl{ width:135px; } + +/** + * Media queries for responsive design. + * + * These follow after primary styles so they will successfully override. + */ + +@media all and (orientation:portrait) { + /* Style adjustments for portrait mode goes here */ + +} + +@media all and (orientation:landscape) { + /* Style adjustments for landscape mode goes here */ + +} + +/* Grade-A Mobile Browsers (Opera Mobile, Mobile Safari, Android Chrome) + consider this: www.cloudfour.com/css-media-query-for-mobile-is-fools-gold/ */ +@media screen and (max-device-width: 480px) { + + + /* Uncomment if you don't want iOS and WinMobile to mobile-optimize the text for you: j.mp/textsizeadjust */ + /* html { -webkit-text-size-adjust:none; -ms-text-size-adjust:none; } */ +} + +/** + * Print styles. + * + * Inlined to avoid required HTTP connection: www.phpied.com/delay-loading-your-print-css/ + */ +@media print { + * { background: transparent !important; color: black !important; text-shadow: none !important; filter:none !important; + -ms-filter: none !important; } /* Black prints faster: sanbeiji.com/archives/953 */ + a, a:visited { color: #444 !important; text-decoration: underline; } + a[href]:after { content: " (" attr(href) ")"; } + abbr[title]:after { content: " (" attr(title) ")"; } + .ir a:after, a[href^="javascript:"]:after, a[href^="#"]:after { content: ""; } /* Don't show links for images, or javascript/internal links */ + pre, blockquote { border: 1px solid #999; page-break-inside: avoid; } + thead { display: table-header-group; } /* css-discuss.incutio.com/wiki/Printing_Tables */ + tr, img { page-break-inside: avoid; } + @page { margin: 0.5cm; } + p, h2, h3 { orphans: 3; widows: 3; } + h2, h3{ page-break-after: avoid; } +} + +/** + * Prettyphoto + */ + +div.pp_default .pp_top,div.pp_default .pp_top .pp_middle,div.pp_default .pp_top .pp_left,div.pp_default .pp_top .pp_right,div.pp_default .pp_bottom,div.pp_default .pp_bottom .pp_left,div.pp_default .pp_bottom .pp_middle,div.pp_default .pp_bottom .pp_right{height:13px}div.pp_default .pp_top .pp_left{background:url(/common/img/prettyPhoto/default/sprite.png) -78px -93px no-repeat}div.pp_default .pp_top .pp_middle{background:url(/common/img/prettyPhoto/default/sprite_x.png) top left repeat-x}div.pp_default .pp_top .pp_right{background:url(/common/img/prettyPhoto/default/sprite.png) -112px -93px no-repeat}div.pp_default .pp_content .ppt{color:#f8f8f8}div.pp_default .pp_content_container .pp_left{background:url(/common/img/prettyPhoto/default/sprite_y.png) -7px 0 repeat-y;padding-left:13px}div.pp_default .pp_content_container .pp_right{background:url(/common/img/prettyPhoto/default/sprite_y.png) top right repeat-y;padding-right:13px}div.pp_default .pp_next:hover{background:url(/common/img/prettyPhoto/default/sprite_next.png) center right no-repeat;cursor:pointer}div.pp_default .pp_previous:hover{background:url(/common/img/prettyPhoto/default/sprite_prev.png) center left no-repeat;cursor:pointer}div.pp_default .pp_expand{background:url(/common/img/prettyPhoto/default/sprite.png) 0 -29px no-repeat;cursor:pointer;width:28px;height:28px}div.pp_default .pp_expand:hover{background:url(/common/img/prettyPhoto/default/sprite.png) 0 -56px no-repeat;cursor:pointer}div.pp_default .pp_contract{background:url(/common/img/prettyPhoto/default/sprite.png) 0 -84px no-repeat;cursor:pointer;width:28px;height:28px}div.pp_default .pp_contract:hover{background:url(/common/img/prettyPhoto/default/sprite.png) 0 -113px no-repeat;cursor:pointer}div.pp_default .pp_close{width:30px;height:30px;background:url(/common/img/prettyPhoto/default/sprite.png) 2px 1px no-repeat;cursor:pointer}div.pp_default .pp_gallery ul li a{background:url(/common/img/prettyPhoto/default/default_thumb.png) center center #f8f8f8;border:1px solid #aaa}div.pp_default .pp_gallery a.pp_arrow_previous,div.pp_default .pp_gallery a.pp_arrow_next{position:static;left:auto}div.pp_default .pp_nav .pp_play,div.pp_default .pp_nav .pp_pause{background:url(/common/img/prettyPhoto/default/sprite.png) -51px 1px no-repeat;height:30px;width:30px}div.pp_default .pp_nav .pp_pause{background-position:-51px -29px}div.pp_default a.pp_arrow_previous,div.pp_default a.pp_arrow_next{background:url(/common/img/prettyPhoto/default/sprite.png) -31px -3px no-repeat;height:20px;width:20px;margin:4px 0 0}div.pp_default a.pp_arrow_next{left:52px;background-position:-82px -3px}div.pp_default .pp_content_container .pp_details{margin-top:5px}div.pp_default .pp_nav{clear:none;height:30px;width:105px;position:relative}div.pp_default .pp_nav .currentTextHolder{font-family:Georgia;font-style:italic;font-color:#999;font-size:11px;left:75px;line-height:25px;position:absolute;top:2px;margin:0;padding:0 0 0 10px}div.pp_default .pp_close:hover,div.pp_default .pp_nav .pp_play:hover,div.pp_default .pp_nav .pp_pause:hover,div.pp_default .pp_arrow_next:hover,div.pp_default .pp_arrow_previous:hover{opacity:0.7}div.pp_default .pp_description{font-size:11px;font-weight:700;line-height:14px;margin:5px 50px 5px 0}div.pp_default .pp_bottom .pp_left{background:url(/common/img/prettyPhoto/default/sprite.png) -78px -127px no-repeat}div.pp_default .pp_bottom .pp_middle{background:url(/common/img/prettyPhoto/default/sprite_x.png) bottom left repeat-x}div.pp_default .pp_bottom .pp_right{background:url(/common/img/prettyPhoto/default/sprite.png) -112px -127px no-repeat}div.pp_default .pp_loaderIcon{background:url(/common/img/prettyPhoto/default/loader.gif) center center no-repeat}div.light_rounded .pp_top .pp_left{background:url(/common/img/prettyPhoto/light_rounded/sprite.png) -88px -53px no-repeat}div.light_rounded .pp_top .pp_right{background:url(/common/img/prettyPhoto/light_rounded/sprite.png) -110px -53px no-repeat}div.light_rounded .pp_next:hover{background:url(/common/img/prettyPhoto/light_rounded/btnNext.png) center right no-repeat;cursor:pointer}div.light_rounded .pp_previous:hover{background:url(/common/img/prettyPhoto/light_rounded/btnPrevious.png) center left no-repeat;cursor:pointer}div.light_rounded .pp_expand{background:url(/common/img/prettyPhoto/light_rounded/sprite.png) -31px -26px no-repeat;cursor:pointer}div.light_rounded .pp_expand:hover{background:url(/common/img/prettyPhoto/light_rounded/sprite.png) -31px -47px no-repeat;cursor:pointer}div.light_rounded .pp_contract{background:url(/common/img/prettyPhoto/light_rounded/sprite.png) 0 -26px no-repeat;cursor:pointer}div.light_rounded .pp_contract:hover{background:url(/common/img/prettyPhoto/light_rounded/sprite.png) 0 -47px no-repeat;cursor:pointer}div.light_rounded .pp_close{width:75px;height:22px;background:url(/common/img/prettyPhoto/light_rounded/sprite.png) -1px -1px no-repeat;cursor:pointer}div.light_rounded .pp_nav .pp_play{background:url(/common/img/prettyPhoto/light_rounded/sprite.png) -1px -100px no-repeat;height:15px;width:14px}div.light_rounded .pp_nav .pp_pause{background:url(/common/img/prettyPhoto/light_rounded/sprite.png) -24px -100px no-repeat;height:15px;width:14px}div.light_rounded .pp_arrow_previous{background:url(/common/img/prettyPhoto/light_rounded/sprite.png) 0 -71px no-repeat}div.light_rounded .pp_arrow_next{background:url(/common/img/prettyPhoto/light_rounded/sprite.png) -22px -71px no-repeat}div.light_rounded .pp_bottom .pp_left{background:url(/common/img/prettyPhoto/light_rounded/sprite.png) -88px -80px no-repeat}div.light_rounded .pp_bottom .pp_right{background:url(/common/img/prettyPhoto/light_rounded/sprite.png) -110px -80px no-repeat}div.dark_rounded .pp_top .pp_left{background:url(/common/img/prettyPhoto/dark_rounded/sprite.png) -88px -53px no-repeat}div.dark_rounded .pp_top .pp_right{background:url(/common/img/prettyPhoto/dark_rounded/sprite.png) -110px -53px no-repeat}div.dark_rounded .pp_content_container .pp_left{background:url(/common/img/prettyPhoto/dark_rounded/contentPattern.png) top left repeat-y}div.dark_rounded .pp_content_container .pp_right{background:url(/common/img/prettyPhoto/dark_rounded/contentPattern.png) top right repeat-y}div.dark_rounded .pp_next:hover{background:url(/common/img/prettyPhoto/dark_rounded/btnNext.png) center right no-repeat;cursor:pointer}div.dark_rounded .pp_previous:hover{background:url(/common/img/prettyPhoto/dark_rounded/btnPrevious.png) center left no-repeat;cursor:pointer}div.dark_rounded .pp_expand{background:url(/common/img/prettyPhoto/dark_rounded/sprite.png) -31px -26px no-repeat;cursor:pointer}div.dark_rounded .pp_expand:hover{background:url(/common/img/prettyPhoto/dark_rounded/sprite.png) -31px -47px no-repeat;cursor:pointer}div.dark_rounded .pp_contract{background:url(/common/img/prettyPhoto/dark_rounded/sprite.png) 0 -26px no-repeat;cursor:pointer}div.dark_rounded .pp_contract:hover{background:url(/common/img/prettyPhoto/dark_rounded/sprite.png) 0 -47px no-repeat;cursor:pointer}div.dark_rounded .pp_close{width:75px;height:22px;background:url(/common/img/prettyPhoto/dark_rounded/sprite.png) -1px -1px no-repeat;cursor:pointer}div.dark_rounded .pp_description{margin-right:85px;color:#fff}div.dark_rounded .pp_nav .pp_play{background:url(/common/img/prettyPhoto/dark_rounded/sprite.png) -1px -100px no-repeat;height:15px;width:14px}div.dark_rounded .pp_nav .pp_pause{background:url(/common/img/prettyPhoto/dark_rounded/sprite.png) -24px -100px no-repeat;height:15px;width:14px}div.dark_rounded .pp_arrow_previous{background:url(/common/img/prettyPhoto/dark_rounded/sprite.png) 0 -71px no-repeat}div.dark_rounded .pp_arrow_next{background:url(/common/img/prettyPhoto/dark_rounded/sprite.png) -22px -71px no-repeat}div.dark_rounded .pp_bottom .pp_left{background:url(/common/img/prettyPhoto/dark_rounded/sprite.png) -88px -80px no-repeat}div.dark_rounded .pp_bottom .pp_right{background:url(/common/img/prettyPhoto/dark_rounded/sprite.png) -110px -80px no-repeat}div.dark_rounded .pp_loaderIcon, div.pp_suse .pp_loaderIcon{background:url(/common/img/prettyPhoto/dark_rounded/loader.gif) center center no-repeat}div.dark_square .pp_left,div.dark_square .pp_middle,div.dark_square .pp_right,div.dark_square .pp_content{background:#000}div.dark_square .pp_description{color:#fff;margin:0 85px 0 0}div.dark_square .pp_loaderIcon{background:url(/common/img/prettyPhoto/dark_square/loader.gif) center center no-repeat}div.dark_square .pp_expand{background:url(/common/img/prettyPhoto/dark_square/sprite.png) -31px -26px no-repeat;cursor:pointer}div.dark_square .pp_expand:hover{background:url(/common/img/prettyPhoto/dark_square/sprite.png) -31px -47px no-repeat;cursor:pointer}div.dark_square .pp_contract{background:url(/common/img/prettyPhoto/dark_square/sprite.png) 0 -26px no-repeat;cursor:pointer}div.dark_square .pp_contract:hover{background:url(/common/img/prettyPhoto/dark_square/sprite.png) 0 -47px no-repeat;cursor:pointer}div.dark_square .pp_close{width:75px;height:22px;background:url(/common/img/prettyPhoto/dark_square/sprite.png) -1px -1px no-repeat;cursor:pointer}div.dark_square .pp_nav{clear:none}div.dark_square .pp_nav .pp_play{background:url(/common/img/prettyPhoto/dark_square/sprite.png) -1px -100px no-repeat;height:15px;width:14px}div.dark_square .pp_nav .pp_pause{background:url(/common/img/prettyPhoto/dark_square/sprite.png) -24px -100px no-repeat;height:15px;width:14px}div.dark_square .pp_arrow_previous{background:url(/common/img/prettyPhoto/dark_square/sprite.png) 0 -71px no-repeat}div.dark_square .pp_arrow_next{background:url(/common/img/prettyPhoto/dark_square/sprite.png) -22px -71px no-repeat}div.dark_square .pp_next:hover{background:url(/common/img/prettyPhoto/dark_square/btnNext.png) center right no-repeat;cursor:pointer}div.dark_square .pp_previous:hover{background:url(/common/img/prettyPhoto/dark_square/btnPrevious.png) center left no-repeat;cursor:pointer}div.light_square .pp_expand{background:url(/common/img/prettyPhoto/light_square/sprite.png) -31px -26px no-repeat;cursor:pointer}div.light_square .pp_expand:hover{background:url(/common/img/prettyPhoto/light_square/sprite.png) -31px -47px no-repeat;cursor:pointer}div.light_square .pp_contract{background:url(/common/img/prettyPhoto/light_square/sprite.png) 0 -26px no-repeat;cursor:pointer}div.light_square .pp_contract:hover{background:url(/common/img/prettyPhoto/light_square/sprite.png) 0 -47px no-repeat;cursor:pointer}div.light_square .pp_close{width:75px;height:22px;background:url(/common/img/prettyPhoto/light_square/sprite.png) -1px -1px no-repeat;cursor:pointer}div.light_square .pp_nav .pp_play{background:url(/common/img/prettyPhoto/light_square/sprite.png) -1px -100px no-repeat;height:15px;width:14px}div.light_square .pp_nav .pp_pause{background:url(/common/img/prettyPhoto/light_square/sprite.png) -24px -100px no-repeat;height:15px;width:14px}div.light_square .pp_arrow_previous{background:url(/common/img/prettyPhoto/light_square/sprite.png) 0 -71px no-repeat}div.light_square .pp_arrow_next{background:url(/common/img/prettyPhoto/light_square/sprite.png) -22px -71px no-repeat}div.light_square .pp_next:hover{background:url(/common/img/prettyPhoto/light_square/btnNext.png) center right no-repeat;cursor:pointer}div.light_square .pp_previous:hover{background:url(/common/img/prettyPhoto/light_square/btnPrevious.png) center left no-repeat;cursor:pointer}div.facebook .pp_top .pp_left{background:url(/common/img/prettyPhoto/facebook/sprite.png) -88px -53px no-repeat}div.facebook .pp_top .pp_middle{background:url(/common/img/prettyPhoto/facebook/contentPatternTop.png) top left repeat-x}div.facebook .pp_top .pp_right{background:url(/common/img/prettyPhoto/facebook/sprite.png) -110px -53px no-repeat}div.facebook .pp_content_container .pp_left{background:url(/common/img/prettyPhoto/facebook/contentPatternLeft.png) top left repeat-y}div.facebook .pp_content_container .pp_right{background:url(/common/img/prettyPhoto/facebook/contentPatternRight.png) top right repeat-y}div.facebook .pp_expand{background:url(/common/img/prettyPhoto/facebook/sprite.png) -31px -26px no-repeat;cursor:pointer}div.facebook .pp_expand:hover{background:url(/common/img/prettyPhoto/facebook/sprite.png) -31px -47px no-repeat;cursor:pointer}div.facebook .pp_contract{background:url(/common/img/prettyPhoto/facebook/sprite.png) 0 -26px no-repeat;cursor:pointer}div.facebook .pp_contract:hover{background:url(/common/img/prettyPhoto/facebook/sprite.png) 0 -47px no-repeat;cursor:pointer}div.facebook .pp_close{width:22px;height:22px;background:url(/common/img/prettyPhoto/facebook/sprite.png) -1px -1px no-repeat;cursor:pointer}div.facebook .pp_description{margin:0 37px 0 0}div.facebook .pp_loaderIcon{background:url(/common/img/prettyPhoto/facebook/loader.gif) center center no-repeat}div.facebook .pp_arrow_previous{background:url(/common/img/prettyPhoto/facebook/sprite.png) 0 -71px no-repeat;height:22px;margin-top:0;width:22px}div.facebook .pp_arrow_previous.disabled{background-position:0 -96px;cursor:default}div.facebook .pp_arrow_next{background:url(/common/img/prettyPhoto/facebook/sprite.png) -32px -71px no-repeat;height:22px;margin-top:0;width:22px}div.facebook .pp_arrow_next.disabled{background-position:-32px -96px;cursor:default}div.facebook .pp_nav{margin-top:0}div.facebook .pp_nav p{font-size:15px;padding:0 3px 0 4px}div.facebook .pp_nav .pp_play{background:url(/common/img/prettyPhoto/facebook/sprite.png) -1px -123px no-repeat;height:22px;width:22px}div.facebook .pp_nav .pp_pause{background:url(/common/img/prettyPhoto/facebook/sprite.png) -32px -123px no-repeat;height:22px;width:22px}div.facebook .pp_next:hover{background:url(/common/img/prettyPhoto/facebook/btnNext.png) center right no-repeat;cursor:pointer}div.facebook .pp_previous:hover{background:url(/common/img/prettyPhoto/facebook/btnPrevious.png) center left no-repeat;cursor:pointer}div.facebook .pp_bottom .pp_left{background:url(/common/img/prettyPhoto/facebook/sprite.png) -88px -80px no-repeat}div.facebook .pp_bottom .pp_middle{background:url(/common/img/prettyPhoto/facebook/contentPatternBottom.png) top left repeat-x}div.facebook .pp_bottom .pp_right{background:url(/common/img/prettyPhoto/facebook/sprite.png) -110px -80px no-repeat}div.pp_pic_holder a:focus{outline:none}div.pp_overlay{background:#000;display:none;left:0;position:absolute;top:0;width:100%;z-index:9500}div.pp_pic_holder{display:none;position:absolute;width:100px;z-index:10000}.pp_content{height:40px;min-width:40px}* html .pp_content{width:40px}.pp_content_container{position:relative;text-align:left;width:100%}.pp_content_container .pp_left{padding-left:20px}.pp_content_container .pp_right{padding-right:20px}.pp_content_container .pp_details{float:left;margin:10px 0 2px}.pp_description{display:none;margin:0}.pp_social{float:left;margin:7px 0 0}.pp_social .facebook{float:left;position:relative;top:-1px;margin-left:5px;width:55px;overflow:hidden}.pp_social .twitter{float:left}.pp_nav{clear:right;float:left;margin:3px 10px 0 0}.pp_nav p{float:left;margin:2px 4px}.pp_nav .pp_play,.pp_nav .pp_pause{float:left;margin-right:4px;text-indent:-10000px}a.pp_arrow_previous,a.pp_arrow_next{display:block;float:left;height:15px;margin-top:3px;overflow:hidden;text-indent:-10000px;width:14px}.pp_hoverContainer{position:absolute;top:0;width:100%;z-index:2000}.pp_gallery{display:none;left:50%;margin-top:-50px;position:absolute;z-index:10000}.pp_gallery div{float:left;overflow:hidden;position:relative}.pp_gallery ul{float:left;height:35px;position:relative;white-space:nowrap;margin:0 0 0 5px;padding:0}.pp_gallery ul a{border:1px rgba(0,0,0,0.5) solid;display:block;float:left;height:33px;overflow:hidden}.pp_gallery ul a img{border:0}.pp_gallery li{display:block;float:left;margin:0 5px 0 0;padding:0}.pp_gallery li.default a{background:url(/common/img/prettyPhoto/facebook/default_thumbnail.gif) 0 0 no-repeat;display:block;height:33px;width:50px}.pp_gallery .pp_arrow_previous,.pp_gallery .pp_arrow_next{margin-top:7px!important}a.pp_next{background:url(/common/img/prettyPhoto/light_rounded/btnNext.png) 10000px 10000px no-repeat;display:block;float:right;height:100%;text-indent:-10000px;width:49%}a.pp_previous{background:url(/common/img/prettyPhoto/light_rounded/btnNext.png) 10000px 10000px no-repeat;display:block;float:left;height:100%;text-indent:-10000px;width:49%}a.pp_expand,a.pp_contract{cursor:pointer;display:none;height:20px;position:absolute;right:30px;text-indent:-10000px;top:10px;width:20px;z-index:20000}a.pp_close{position:absolute;right:0;top:0;display:block;line-height:22px;text-indent:-10000px}.pp_loaderIcon{display:block;height:24px;left:50%;position:absolute;top:50%;width:24px;margin:-12px 0 0 -12px}#pp_full_res{line-height:1!important}#pp_full_res .pp_inline{text-align:left}#pp_full_res .pp_inline p{margin:0 0 15px}div.ppt{color:#fff;display:none;font-size:17px;z-index:9999;margin:0 0 5px 15px}div.pp_default .pp_content,div.light_rounded .pp_content{background-color:#fff}div.pp_default #pp_full_res .pp_inline,div.light_rounded .pp_content .ppt,div.light_rounded #pp_full_res .pp_inline,div.light_square .pp_content .ppt,div.light_square #pp_full_res .pp_inline,div.facebook .pp_content .ppt,div.facebook #pp_full_res .pp_inline{color:#000}div.pp_default .pp_gallery ul li a:hover,div.pp_default .pp_gallery ul li.selected a,.pp_gallery ul a:hover,.pp_gallery li.selected a{border-color:#fff}div.pp_default .pp_details,div.light_rounded .pp_details,div.dark_rounded .pp_details,div.dark_square .pp_details,div.light_square .pp_details,div.facebook .pp_details{position:relative}div.light_rounded .pp_top .pp_middle,div.light_rounded .pp_content_container .pp_left,div.light_rounded .pp_content_container .pp_right,div.light_rounded .pp_bottom .pp_middle,div.light_square .pp_left,div.light_square .pp_middle,div.light_square .pp_right,div.light_square .pp_content,div.facebook .pp_content{background:#fff}div.light_rounded .pp_description,div.light_square .pp_description{margin-right:85px}div.light_rounded .pp_gallery a.pp_arrow_previous,div.light_rounded .pp_gallery a.pp_arrow_next,div.dark_rounded .pp_gallery a.pp_arrow_previous,div.dark_rounded .pp_gallery a.pp_arrow_next,div.dark_square .pp_gallery a.pp_arrow_previous,div.dark_square .pp_gallery a.pp_arrow_next,div.light_square .pp_gallery a.pp_arrow_previous,div.light_square .pp_gallery a.pp_arrow_next{margin-top:12px!important}div.light_rounded .pp_arrow_previous.disabled,div.dark_rounded .pp_arrow_previous.disabled,div.dark_square .pp_arrow_previous.disabled,div.light_square .pp_arrow_previous.disabled{background-position:0 -87px;cursor:default}div.light_rounded .pp_arrow_next.disabled,div.dark_rounded .pp_arrow_next.disabled,div.dark_square .pp_arrow_next.disabled,div.light_square .pp_arrow_next.disabled{background-position:-22px -87px;cursor:default}div.light_rounded .pp_loaderIcon,div.light_square .pp_loaderIcon{background:url(/common/img/prettyPhoto/light_rounded/loader.gif) center center no-repeat}div.dark_rounded .pp_top .pp_middle,div.dark_rounded .pp_content,div.dark_rounded .pp_bottom .pp_middle{background:url(/common/img/prettyPhoto/dark_rounded/contentPattern.png) top left repeat}div.dark_rounded .currentTextHolder,div.dark_square .currentTextHolder{color:#c4c4c4}div.dark_rounded #pp_full_res .pp_inline,div.dark_square #pp_full_res .pp_inline{color:#fff}.pp_top,.pp_bottom{height:20px;position:relative}* html .pp_top,* html .pp_bottom{padding:0 20px}.pp_top .pp_left,.pp_bottom .pp_left{height:20px;left:0;position:absolute;width:20px}.pp_top .pp_middle,.pp_bottom .pp_middle{height:20px;left:20px;position:absolute;right:20px}* html .pp_top .pp_middle,* html .pp_bottom .pp_middle{left:0;position:static}.pp_top .pp_right,.pp_bottom .pp_right{height:20px;left:auto;position:absolute;right:0;top:0;width:20px}.pp_fade,.pp_gallery li.default a img{display:none} + +.pp_suse .pp_content{ background:none !important; } +.pp_suse div.ppt{ height:0; margin:0; display:none !important; } +.pp_suse div.ppt_custom{ display:none; background:#fff; width:300px !important; padding:40px 0 0 28px; font-size:21px; margin:0; z-index:9999; color:#439539; position:relative; font-family:"omnes-pro-1", Arial, sans-serif; } +.pp_suse a.pp_close{ top:19px; right:28px; background-image:url(/common/img/x.gif); width:10px; height:10px; background-position:0px 0px; } +#suse_overlay_iframe{ overflow:hidden; } +.pp_margin{ top:150px !important; } + + +/** + * qtip + */ + +.ui-tooltip,.qtip{position:absolute;left:-28000px;top:-28000px;display:none;max-width:280px;min-width:50px;font-size:14px;line-height:12px;z-index:15000;}.ui-tooltip-fluid{display:block;visibility:hidden;position:static!important;float:left!important;}.ui-tooltip-content{position:relative;padding:12px 12px 9px 12px;overflow:hidden;border-width:1px;border-style:solid;text-align:left;word-wrap:break-word;overflow:hidden;}.ui-tooltip-titlebar{position:relative;min-height:14px;padding:5px 35px 5px 10px;overflow:hidden;border-width:1px 1px 0;border-style:solid;font-weight:bold;}.ui-tooltip-titlebar+.ui-tooltip-content{border-top-width:0!important;}/*!Default close button class */ .ui-tooltip-titlebar .ui-state-default{position:absolute;right:4px;top:50%;margin-top:-9px;cursor:pointer;outline:medium none;border-width:1px;border-style:solid;}* html .ui-tooltip-titlebar .ui-state-default{top:16px;}.ui-tooltip-titlebar .ui-icon,.ui-tooltip-icon .ui-icon{display:block;text-indent:-1000em;}.ui-tooltip-icon,.ui-tooltip-icon .ui-icon{-moz-border-radius:3px;-webkit-border-radius:3px;border-radius:3px;}.ui-tooltip-icon .ui-icon{width:18px;height:14px;text-align:center;text-indent:0;font:normal bold 10px/13px Tahoma,sans-serif;color:inherit;background:transparent none no-repeat -100em -100em;}/*!Default tooltip style */ .ui-tooltip-default .ui-tooltip-titlebar,.ui-tooltip-default .ui-tooltip-content{border-color:#F1D031;background-color:#FFFFA3;color:#333;}.ui-tooltip-default .ui-tooltip-titlebar{background-color:#FFEF93;}.ui-tooltip-default .ui-tooltip-icon{border-color:#CCC;background:#F1F1F1;color:#777;}.ui-tooltip-default .ui-tooltip-titlebar .ui-state-hover{border-color:#AAA;color:#111;}.ui-tooltip .ui-tooltip-tip{margin:0 auto;overflow:hidden;background:transparent!important;border:0 dashed transparent!important;z-index:10;}.ui-tooltip .ui-tooltip-tip,.ui-tooltip .ui-tooltip-tip *{position:absolute;line-height:.1px!important;font-size:.1px!important;color:#123456;background:transparent;border:0 dashed transparent;}.ui-tooltip .ui-tooltip-tip canvas{top:0;left:0;}/*!Light tooltip style */ .ui-tooltip-light .ui-tooltip-titlebar,.ui-tooltip-light .ui-tooltip-content{border-color:#E2E2E2;color:#454545;}.ui-tooltip-light .ui-tooltip-content{background-color:white;}.ui-tooltip-light .ui-tooltip-titlebar{background-color:#f1f1f1;}/*!Dark tooltip style */ .ui-tooltip-dark .ui-tooltip-titlebar,.ui-tooltip-dark .ui-tooltip-content{border-color:#303030;color:#f3f3f3;}.ui-tooltip-dark .ui-tooltip-content{background-color:#505050;}.ui-tooltip-dark .ui-tooltip-titlebar{background-color:#404040;}.ui-tooltip-dark .ui-tooltip-icon{border-color:#444;}.ui-tooltip-dark .ui-tooltip-titlebar .ui-state-hover{border-color:#303030;}/*!Cream tooltip style */ .ui-tooltip-cream .ui-tooltip-titlebar,.ui-tooltip-cream .ui-tooltip-content{border-color:#F9E98E;color:#A27D35;}.ui-tooltip-cream .ui-tooltip-content{background-color:#FBF7AA;}.ui-tooltip-cream .ui-tooltip-titlebar{background-color:#F0DE7D;}.ui-tooltip-cream .ui-state-default .ui-tooltip-icon{background-position:-82px 0;}/*!Red tooltip style */ .ui-tooltip-red .ui-tooltip-titlebar,.ui-tooltip-red .ui-tooltip-content{border-color:#D95252;color:#912323;}.ui-tooltip-red .ui-tooltip-content{background-color:#F78B83;}.ui-tooltip-red .ui-tooltip-titlebar{background-color:#F06D65;}.ui-tooltip-red .ui-state-default .ui-tooltip-icon{background-position:-102px 0;}.ui-tooltip-red .ui-tooltip-icon{border-color:#D95252;}.ui-tooltip-red .ui-tooltip-titlebar .ui-state-hover{border-color:#D95252;}/*!Green tooltip style */ .ui-tooltip-green .ui-tooltip-titlebar,.ui-tooltip-green .ui-tooltip-content{border-color:#D7FB60;color:#3F6219;}.ui-tooltip-green .ui-tooltip-content{background-color:#D7FB60;}.ui-tooltip-green .ui-tooltip-titlebar{background-color:#B0DE78;}.ui-tooltip-green .ui-state-default .ui-tooltip-icon{background-position:-42px 0;}/*!Blue tooltip style */ .ui-tooltip-blue .ui-tooltip-titlebar,.ui-tooltip-blue .ui-tooltip-content{border-color:#ADD9ED;color:#5E99BD;}.ui-tooltip-blue .ui-tooltip-content{background-color:#E5F6FE;}.ui-tooltip-blue .ui-tooltip-titlebar{background-color:#D0E9F5;}.ui-tooltip-blue .ui-state-default .ui-tooltip-icon{background-position:-2px 0;}/*!Add shadows to your tooltips in:FF3+,Chrome 2+,Opera 10.6+,IE6+,Safari 2+*/ .ui-tooltip-shadow{-webkit-box-shadow:1px 1px 3px 1px rgba(0,0,0,0.15);-moz-box-shadow:1px 1px 3px 1px rgba(0,0,0,0.15);box-shadow:1px 1px 3px 1px rgba(0,0,0,0.15);}.ui-tooltip-shadow .ui-tooltip-titlebar,.ui-tooltip-shadow .ui-tooltip-content{filter:progid:DXImageTransform.Microsoft.Shadow(Color='gray',Direction=135,Strength=3);-ms-filter:"progid:DXImageTransform.Microsoft.Shadow(Color='gray',Direction=135,Strength=3)";_margin-bottom:-3px;.margin-bottom:-3px;}/*!Add rounded corners to your tooltips in:FF3+,Chrome 2+,Opera 10.6+,IE9+,Safari 2+*/ .ui-tooltip-rounded,.ui-tooltip-rounded .ui-tooltip-content,.ui-tooltip-tipsy,.ui-tooltip-tipsy .ui-tooltip-content,.ui-tooltip-youtube,.ui-tooltip-youtube .ui-tooltip-content{-moz-border-radius:4px;-webkit-border-radius:4px;border-radius:4px;}.ui-tooltip-rounded .ui-tooltip-titlebar,.ui-tooltip-tipsy .ui-tooltip-titlebar,.ui-tooltip-youtube .ui-tooltip-titlebar{-moz-border-radius:5px 5px 0 0;-webkit-border-radius:5px 5px 0 0;border-radius:5px 5px 0 0;}.ui-tooltip-rounded .ui-tooltip-titlebar+.ui-tooltip-content,.ui-tooltip-tipsy .ui-tooltip-titlebar+.ui-tooltip-content,.ui-tooltip-youtube .ui-tooltip-titlebar+.ui-tooltip-content{-moz-border-radius:0 0 5px 5px;-webkit-border-radius:0 0 5px 5px;border-radius:0 0 5px 5px;}/*!Youtube tooltip style */ .ui-tooltip-youtube{-webkit-box-shadow:0 0 3px #333;-moz-box-shadow:0 0 3px #333;box-shadow:0 0 3px #333;}.ui-tooltip-youtube .ui-tooltip-titlebar,.ui-tooltip-youtube .ui-tooltip-content{_margin-bottom:0;.margin-bottom:0;background:transparent;background:rgba(0,0,0,0.85);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr=#D9000000,endColorstr=#D9000000);-ms-filter:"progid:DXImageTransform.Microsoft.gradient(startColorstr=#D9000000,endColorstr=#D9000000)";color:white;border-color:#CCC;}.ui-tooltip-youtube .ui-tooltip-icon{border-color:#222;}.ui-tooltip-youtube .ui-tooltip-titlebar .ui-state-hover{border-color:#303030;}.ui-tooltip-jtools{background:#232323;background:rgba(0,0,0,0.7);background-image:-moz-linear-gradient(top,#717171,#232323);background-image:-webkit-gradient(linear,left top,left bottom,from(#717171),to(#232323));border:2px solid #ddd;border:2px solid rgba(241,241,241,1);-moz-border-radius:2px;-webkit-border-radius:2px;border-radius:2px;-webkit-box-shadow:0 0 12px #333;-moz-box-shadow:0 0 12px #333;box-shadow:0 0 12px #333;}.ui-tooltip-jtools .ui-tooltip-titlebar{filter:progid:DXImageTransform.Microsoft.gradient(startColorstr=#717171,endColorstr=#4A4A4A);-ms-filter:"progid:DXImageTransform.Microsoft.gradient(startColorstr=#717171,endColorstr=#4A4A4A)";}.ui-tooltip-jtools .ui-tooltip-content{filter:progid:DXImageTransform.Microsoft.gradient(startColorstr=#4A4A4A,endColorstr=#232323);-ms-filter:"progid:DXImageTransform.Microsoft.gradient(startColorstr=#4A4A4A,endColorstr=#232323)";}.ui-tooltip-jtools .ui-tooltip-titlebar,.ui-tooltip-jtools .ui-tooltip-content{background:transparent;color:white;border:0 dashed transparent;}.ui-tooltip-jtools .ui-tooltip-icon{border-color:#555;}.ui-tooltip-jtools .ui-tooltip-titlebar .ui-state-hover{border-color:#333;}.ui-tooltip-cluetip{-webkit-box-shadow:4px 4px 5px rgba(0,0,0,0.4);-moz-box-shadow:4px 4px 5px rgba(0,0,0,0.4);box-shadow:4px 4px 5px rgba(0,0,0,0.4);}.ui-tooltip-cluetip .ui-tooltip-titlebar{background-color:#87876A;color:white;border:0 dashed transparent;}.ui-tooltip-cluetip .ui-tooltip-content{background-color:#D9D9C2;color:#111;border:0 dashed transparent;}.ui-tooltip-cluetip .ui-tooltip-icon{border-color:#808064;}.ui-tooltip-cluetip .ui-tooltip-titlebar .ui-state-hover{border-color:#696952;color:#696952;}.ui-tooltip-tipsy{border:0;}.ui-tooltip-tipsy .ui-tooltip-titlebar,.ui-tooltip-tipsy .ui-tooltip-content{_margin-bottom:0;.margin-bottom:0;background:transparent;background:rgba(0,0,0,.87);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr=#D9000000,endColorstr=#D9000000);-ms-filter:"progid:DXImageTransform.Microsoft.gradient(startColorstr=#D9000000,endColorstr=#D9000000)";color:white;border:0 transparent;font-size:11px;font-family:'Lucida Grande',sans-serif;font-weight:bold;line-height:16px;text-shadow:0 1px black;}.ui-tooltip-tipsy .ui-tooltip-titlebar{padding:6px 35px 0 10;}.ui-tooltip-tipsy .ui-tooltip-content{padding:6px 10;}.ui-tooltip-tipsy .ui-tooltip-icon{border-color:#222;text-shadow:none;}.ui-tooltip-tipsy .ui-tooltip-titlebar .ui-state-hover{border-color:#303030;}.ui-tooltip-tipped .ui-tooltip-titlebar,.ui-tooltip-tipped .ui-tooltip-content{border:3px solid #959FA9;filter:none;-ms-filter:none;}.ui-tooltip-tipped .ui-tooltip-titlebar{background:#3A79B8;background-image:-moz-linear-gradient(top,#3A79B8,#2E629D);background-image:-webkit-gradient(linear,left top,left bottom,from(#3A79B8),to(#2E629D));filter:progid:DXImageTransform.Microsoft.gradient(startColorstr=#3A79B8,endColorstr=#2E629D);-ms-filter:"progid:DXImageTransform.Microsoft.gradient(startColorstr=#3A79B8,endColorstr=#2E629D)";color:white;font-weight:normal;font-family:serif;border-bottom-width:0;-moz-border-radius:3px 3px 0 0;-webkit-border-radius:3px 3px 0 0;border-radius:3px 3px 0 0;}.ui-tooltip-tipped .ui-tooltip-content{background-color:#F9F9F9;color:#454545;-moz-border-radius:0 0 3px 3px;-webkit-border-radius:0 0 3px 3px;border-radius:0 0 3px 3px;}.ui-tooltip-tipped .ui-tooltip-icon{border:2px solid #285589;background:#285589;}.ui-tooltip-tipped .ui-tooltip-icon .ui-icon{background-color:#FBFBFB;color:#555;}.ui-tooltip:not(.ie9haxors) div.ui-tooltip-content,.ui-tooltip:not(.ie9haxors) div.ui-tooltip-titlebar{filter:none;-ms-filter:none;} + +/** + * jScrollPayne + */ + +.jScrollPaneContainer { + position: relative; + overflow: hidden; + z-index: 1; +} + +.jScrollPaneTrack { + position: absolute; + cursor: pointer; + right: 0; + top: 0; + height: 100%; + background: #aaa; +} +.jScrollPaneDrag { + position: absolute; + background: #666; + cursor: pointer; + overflow: hidden; +} +.jScrollPaneDragTop { + position: absolute; + top: 0; + left: 0; + overflow: hidden; +} +.jScrollPaneDragBottom { + position: absolute; + bottom: 0; + left: 0; + overflow: hidden; +} +a.jScrollArrowUp { + display: block; + position: absolute; + z-index: 1; + top: 0; + right: 0; + text-indent: -2000px; + overflow: hidden; + /*background-color: #666;*/ + height: 9px; +} +a.jScrollArrowUp:hover { + /*background-color: #f60;*/ +} + +a.jScrollArrowDown { + display: block; + position: absolute; + z-index: 1; + bottom: 0; + right: 0; + text-indent: -2000px; + overflow: hidden; + /*background-color: #666;*/ + height: 9px; +} +a.jScrollArrowDown:hover { + /*background-color: #f60;*/ +} +a.jScrollActiveArrowButton, a.jScrollActiveArrowButton:hover { + /*background-color: #f00;*/ +}
\ No newline at end of file diff --git a/tests2/files/x.css b/tests2/files/x.css new file mode 100644 index 00000000..b744f4ce --- /dev/null +++ b/tests2/files/x.css @@ -0,0 +1,13 @@ +@IMPORT "http://example.com" + +@media print { + * { + background: transparent !important; color: black !important; text-shadow: none !important; filter:none !important +; + -ms-filter: none !important; + } /* Black prints faster: sanbeiji.com/archives/953 */ +header #search{ width:138px; height:25px; background:url(/common/img/search.png) top left no-repeat; position:absolute; top:12px; right:20px; } + background:url( '/common/img/search.png' ); + background:url( '//example.com/common/img/search.png' ); + background:url("/common/img/search.png"); +} diff --git a/tests2/libtest.c b/tests2/libtest.c new file mode 100644 index 00000000..a775732c --- /dev/null +++ b/tests2/libtest.c @@ -0,0 +1,850 @@ +/* + * Copyright(c) 2013-2014 Tim Ruehsen + * + * This file is part of libwget. + * + * Libwget is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Libwget is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with libwget. If not, see <http://www.gnu.org/licenses/>. + * + * + * Test suite function library + * + * Changelog + * 16.01.2013 Tim Ruehsen created + * + * To create the X.509 stuff, I followed the instructions at + * gnutls.org/manual/html_node/gnutls_002dserv-Invocation.html + * + */ + +#if HAVE_CONFIG_H +# include <config.h> +#endif + +#include <stdlib.h> +#include <unistd.h> +#include <string.h> +#include <errno.h> +#include <fcntl.h> +#include <signal.h> +#include <utime.h> +#include <dirent.h> +#include <ctype.h> +#include <sys/stat.h> +#include <sys/time.h> +#include <sys/wait.h> +#include <libwget.h> + +#include "libtest.h" + +static wget_thread_t + http_server_tid, + https_server_tid, + ftp_server_tid, + ftps_server_tid; +static int + http_server_port, + https_server_port, + ftp_server_port, + ftps_server_port, + ftps_implicit, + terminate, + keep_tmpfiles; +/*static const char + *response_code = "200 Dontcare", + *response_body = ""; +static WGET_VECTOR + *response_headers; */ +static wget_vector_t + *request_urls; +static wget_test_url_t + *urls; +static size_t + nurls; +static wget_test_ftp_io_t + *ios; +static size_t + nios; +static int + ios_ordered; +static char + tmpdir[128]; +static const char + *server_hello; + +static void sigterm_handler(int sig G_GNUC_WGET_UNUSED) +{ + terminate = 1; +} + +static void *_http_server_thread(void *ctx) +{ + wget_tcp_t *tcp=NULL, *parent_tcp = ctx; + wget_test_url_t *url = NULL; + char buf[4096], method[32], request_url[256], tag[64], value[256], *p; + ssize_t nbytes, from_bytes, to_bytes; + size_t body_len, request_url_length; + unsigned it; + int byterange, authorized; + time_t modified; + +#if defined(_WIN32) || defined(_WIN64) + signal(SIGTERM, sigterm_handler); +#else + sigaction(SIGTERM, &(struct sigaction) { .sa_handler = sigterm_handler }, NULL); +#endif + + while (!terminate) { + wget_tcp_deinit(&tcp); + + if ((tcp = wget_tcp_accept(parent_tcp))) { + authorized = 0; + + // as a quick hack, just assume that request comes in one packet + if ((nbytes = wget_tcp_read(tcp, buf, sizeof(buf)-1)) > 0) { + buf[nbytes]=0; + if (sscanf(buf, "%31s %255s", method, request_url) !=2) { + wget_tcp_printf(tcp, "HTTP/1.1 400 Bad Request\r\nConnection: close\r\n\r\n"); + continue; + } + + byterange = from_bytes = to_bytes = 0; + modified = 0; + + for (p = strstr(buf, "\r\n"); sscanf(p, "\r\n%63[^:]: %255[^\r]", tag, value) == 2; p = strstr(p + 2, "\r\n")) { + if (!wget_strcasecmp_ascii(tag, "Range")) { + if ((byterange = sscanf(value, "bytes=%zd-%zd", &from_bytes, &to_bytes)) < 1) + byterange = 0; + } + else if (url && !wget_strcasecmp_ascii(tag, "Authorization")) { + const char *auth_scheme, *s; + + s=wget_http_parse_token(value, &auth_scheme); + while (isblank(*s)) s++; + + if (!wget_strcasecmp_ascii(auth_scheme, "basic")) { + const char *encoded = wget_base64_encode_printf_alloc("%s:%s", url->auth_username, url->auth_password); + + wget_error_printf("Auth check '%s' <-> '%s'\n", encoded, s); + if (!strcmp(encoded, s)) + authorized = 1; + + wget_xfree(encoded); + } + + wget_xfree(auth_scheme); + } + else if (!wget_strcasecmp_ascii(tag, "If-Modified-Since")) { + modified = wget_http_parse_full_date(value); + wget_info_printf("modified = %ld\n", modified); + } + } + + url = NULL; + request_url_length = strlen(request_url); + + if (request_url[request_url_length - 1] == '/') { + // access a directory + for (it = 0; it < nurls; it++) { + if (!strcmp(request_url, urls[it].name) || + (!strncmp(request_url, urls[it].name, request_url_length) && + !strcmp(urls[it].name + request_url_length, "index.html"))) + { + url = &urls[it]; + break; + } + } + } else { + // access a file + for (it = 0; it < nurls; it++) { + // printf("%s %s\n", request_url, urls[it].name); + if (!strcmp(request_url, urls[it].name)) { + url = &urls[it]; + break; + } + } + } + + if (!url) { + wget_tcp_printf(tcp, "HTTP/1.1 404 Not Found\r\nConnection: close\r\n\r\n"); + continue; + } + + if (url->auth_method && !authorized) { + if (!wget_strcasecmp_ascii(url->auth_method, "basic")) + wget_tcp_printf(tcp, + "HTTP/1.1 401 Unauthorized\r\n" \ + "WWW-Authenticate: %s realm=\"Protected Page\"\r\n" \ + "Connection: close\r\n\r\n", + url->auth_method); + else + wget_error_printf(_("Unknown authentication scheme '%s'\n"), url->auth_method); + + continue; + } + + if (modified && url->modified<=modified) { + wget_tcp_printf(tcp,"HTTP/1.1 304 Not Modified\r\n\r\n"); + continue; + } + + if (byterange == 1) { + to_bytes = strlen(url->body) - 1; + } + if (byterange) { + if (from_bytes > to_bytes || from_bytes >= (int)strlen(url->body)) { + wget_tcp_printf(tcp, "HTTP/1.1 416 Range Not Satisfiable\r\nConnection: close\r\n\r\n"); + continue; + } + + // create response + body_len = to_bytes - from_bytes + 1; + nbytes = snprintf(buf, sizeof(buf), + "HTTP/1.1 206 Partial Content\r\n"\ + "Content-Length: %zu\r\n"\ + "Accept-Ranges: bytes\r\n"\ + "Content-Range: %zd-%zd/%zu\r\n", + body_len, from_bytes, to_bytes, body_len); + for (it = 0; it < countof(url->headers) && url->headers[it]; it++) { + nbytes += snprintf(buf + nbytes, sizeof(buf) - nbytes, "%s\r\n", url->headers[it]); + } + nbytes += snprintf(buf + nbytes, sizeof(buf) - nbytes, "\r\n"); + if (!strcmp(method, "GET") || !strcmp(method, "POST")) + nbytes += snprintf(buf + nbytes, sizeof(buf) - nbytes, "%.*s", (int)body_len, url->body + from_bytes); + } else { + // create response + body_len = strlen(url->body ? url->body : ""); + nbytes = snprintf(buf, sizeof(buf), + "HTTP/1.1 %s\r\n"\ + "Content-Length: %zu\r\n", + url->code ? url->code : "200 OK\r\n", body_len); + for (it = 0; it < countof(url->headers) && url->headers[it]; it++) { + nbytes += snprintf(buf + nbytes, sizeof(buf) - nbytes, "%s\r\n", url->headers[it]); + } + nbytes += snprintf(buf + nbytes, sizeof(buf) - nbytes, "\r\n"); + if (!strcmp(method, "GET") || !strcmp(method, "POST")) + nbytes += snprintf(buf + nbytes, sizeof(buf) - nbytes, "%s", url->body ? url->body : ""); + } + + // send response + wget_tcp_write(tcp, buf, nbytes); + } + } else if (!terminate) + wget_error_printf(_("Failed to get connection (%d)\n"), errno); + } + + wget_tcp_deinit(&parent_tcp); + + return NULL; +} + +static void *_ftp_server_thread(void *ctx) +{ + wget_tcp_t *tcp = NULL, *parent_tcp = ctx, *pasv_parent_tcp = NULL, *pasv_tcp = NULL; + char buf[4096]; + ssize_t nbytes; + int pasv_port, found; + unsigned io_pos; + +#if defined(_WIN32) || defined(_WIN64) + signal(SIGTERM, sigterm_handler); +#else + sigaction(SIGTERM, &(struct sigaction) { .sa_handler = sigterm_handler }, NULL); +#endif + + while (!terminate) { + wget_tcp_deinit(&tcp); + wget_tcp_deinit(&pasv_tcp); + wget_tcp_deinit(&pasv_parent_tcp); + + if ((tcp = wget_tcp_accept(parent_tcp))) { + io_pos = 0; + + if (server_hello) + wget_tcp_printf(tcp, "%s\r\n", server_hello); + + // as a quick hack, just assume that each line comes in one packet + while ((nbytes = wget_tcp_read(tcp, buf, sizeof(buf)-1)) > 0) { + buf[nbytes] = 0; + + while (--nbytes >= 0 && (buf[nbytes] == '\r' || buf[nbytes] == '\n')) + buf[nbytes] = 0; + + wget_debug_printf("### Got: '%s'\n", buf); + + found = 0; + if (ios_ordered) { + if (!strcmp(buf, ios[io_pos].in)) + found = 1; + } else { + for (io_pos = 0; io_pos < nios; io_pos++) { + if (!strcmp(buf, ios[io_pos].in)) { + found = 1; + break; + } + } + } + if (!found) { + wget_error_printf(_("Unexpected input: '%s'\n"), buf); + wget_tcp_printf(tcp, "500 Unknown command\r\n"); + continue; + } + + if (!strncmp(buf, "AUTH", 4)) { + // assume TLS auth type + wget_tcp_printf(tcp, "%s\r\n", ios[io_pos].out); + if (atoi(ios[io_pos].out)/100 == 2) + wget_tcp_tls_start(tcp); + io_pos++; + continue; + } + + if (!strncmp(buf, "PASV", 4) || !strncmp(buf, "EPSV", 4)) { + // init FTP PASV/EPSV socket + // we ignore EPSV address type here, we listen on IPv4 and IPv6 anyways + pasv_parent_tcp=wget_tcp_init(); + wget_tcp_set_timeout(pasv_parent_tcp, -1); // INFINITE timeout + if (!strncmp(buf, "EPSV", 4)) { + switch (atoi(buf+4)) { + case 1: wget_tcp_set_family(pasv_parent_tcp, WGET_NET_FAMILY_IPV4); break; + case 2: wget_tcp_set_family(pasv_parent_tcp, WGET_NET_FAMILY_IPV6); break; + default: wget_tcp_set_family(pasv_parent_tcp, WGET_NET_FAMILY_ANY); break; + } + } + if (wget_tcp_listen(pasv_parent_tcp, "localhost", NULL, 5) != 0) { + wget_tcp_printf(tcp, "500 failed to open port\r\n"); + break; + } + pasv_port = wget_tcp_get_local_port(pasv_parent_tcp); + + const char *src = ios[io_pos].out; + char *response = wget_malloc(strlen(src) + 32 + 1); + char *dst = response; + + while (*src) { + if (*src == '{') { + if (!strncmp(src, "{{pasvdata}}", 12)) { + if (!strncmp(buf, "EPSV", 4)) + dst += sprintf(dst, "(|||%d|)", pasv_port); + else + dst += sprintf(dst, "(127,0,0,1,%d,%d)", pasv_port / 256, pasv_port % 256); + src += 12; + continue; + } + } + *dst++ = *src++; + } + *dst = 0; + + wget_tcp_printf(tcp, "%s\r\n", response); + wget_xfree(response); + + if (!(pasv_tcp = wget_tcp_accept(pasv_parent_tcp))) { + wget_error_printf(_("Failed to get PASV connection\n")); + break; + } + } else { + wget_tcp_printf(tcp, "%s\r\n", ios[io_pos].out); + } + + if (ios[io_pos].send_url && pasv_tcp) { + // send data + wget_tcp_printf(pasv_tcp, "%s", ios[io_pos].send_url->body); + wget_tcp_deinit(&pasv_tcp); + wget_tcp_printf(tcp, "226 Transfer complete\r\n"); + } + + io_pos++; + } + } else if (!terminate) + wget_error_printf(_("Failed to get connection (%d)\n"), errno); + } + + wget_tcp_deinit(&parent_tcp); + + return NULL; +} + +// To reduce the verbosity of 'valgrind --trace-children=yes' output, +// we avoid system("rm -rf ...") calls. +static void _remove_directory(const char *dirname); +static void _empty_directory(const char *dirname) +{ + DIR *dir; + struct dirent *dp; + size_t dirlen = strlen(dirname); + + if ((dir = opendir(dirname))) { + while ((dp = readdir(dir))) { + if (*dp->d_name == '.' && (dp->d_name[1] == 0 || (dp->d_name[1] == '.' && dp->d_name[2] == 0))) + continue; + + char fname[dirlen + 1 + strlen(dp->d_name) + 1]; + snprintf(fname, sizeof(fname), "%s/%s", dirname, dp->d_name); + + if (unlink(fname) == -1) { + if (errno == EISDIR) + _remove_directory(fname); + else + wget_error_printf(_("Failed to unlink %s (%d)\n"), fname, errno); + } + } + + closedir(dir); + } else + wget_error_printf(_("Failed to opendir %s\n"), dirname); +} + +static void _remove_directory(const char *dirname) +{ + _empty_directory(dirname); + if (rmdir(dirname) == -1) + wget_error_printf(_("Failed to rmdir %s\n"), dirname); +} + +void wget_test_stop_server(void) +{ + size_t it; + +// wget_vector_free(&response_headers); + wget_vector_free(&request_urls); + + for (it = 0; it < nurls; it++) { + if (urls[it].body_alloc) { + wget_xfree(urls[it].body); + urls[it].body_alloc = 0; + } + } + + if (chdir("..") != 0) + wget_error_printf(_("Failed to chdir ..\n")); + + if (!keep_tmpfiles) + _remove_directory(tmpdir); + + // free resources - needed for valgrind testing + pthread_kill(http_server_tid, SIGTERM); + pthread_kill(https_server_tid, SIGTERM); + pthread_kill(ftp_server_tid, SIGTERM); + if (ftps_implicit) + pthread_kill(ftps_server_tid, SIGTERM); + + wget_thread_join(http_server_tid); + wget_thread_join(https_server_tid); + wget_thread_join(ftp_server_tid); + if (ftps_implicit) + wget_thread_join(ftps_server_tid); + + wget_global_deinit(); +} + +void wget_test_start_server(int first_key, ...) +{ + static wget_tcp_t *http_parent_tcp, *https_parent_tcp, *ftp_parent_tcp, *ftps_parent_tcp; + int rc, key; + size_t it; + va_list args; + + wget_global_init( + WGET_DEBUG_STREAM, stderr, + WGET_ERROR_STREAM, stderr, +// WGET_INFO_STREAM, stdout, + NULL); + + va_start(args, first_key); + for (key = first_key; key; key = va_arg(args, int)) { + switch (key) { +/* case WGET_TEST_RESPONSE_BODY: + response_body = va_arg(args, const char *); + break; + case WGET_TEST_RESPONSE_HEADER: + if (!response_headers) + response_headers = wget_vector_create(4,4,NULL); + wget_vector_add_str(response_headers, va_arg(args, const char *)); + break; + case WGET_TEST_RESPONSE_CODE: + response_code = va_arg(args, const char *); + break; +*/ case WGET_TEST_EXPECTED_REQUEST_HEADER: + break; + case WGET_TEST_RESPONSE_URLS: + urls = va_arg(args, wget_test_url_t *); + nurls = va_arg(args, size_t); + break; + case WGET_TEST_FTP_SERVER_HELLO: + server_hello = va_arg(args, const char *); + case WGET_TEST_FTP_IO_ORDERED: + ios_ordered = 1; + ios = va_arg(args, wget_test_ftp_io_t *); + nios = va_arg(args, size_t); + case WGET_TEST_FTP_IO_UNORDERED: + ios_ordered = 0; + ios = va_arg(args, wget_test_ftp_io_t *); + nios = va_arg(args, size_t); + break; + case WGET_TEST_FTPS_IMPLICIT: + ftps_implicit = va_arg(args, int); + break; + default: + wget_error_printf(_("Unknown option %d\n"), key); + } + } + va_end(args); + + atexit(wget_test_stop_server); + + snprintf(tmpdir, sizeof(tmpdir), ".test_%d", (int) getpid()); + +#if defined(_WIN32) || defined(_WIN64) + if (mkdir(tmpdir) != 0) +#else + if (mkdir(tmpdir, 0755) != 0) +#endif + wget_error_printf_exit(_("Failed to create tmpdir (%d)\n"), errno); + + if (chdir(tmpdir) != 0) + wget_error_printf_exit(_("Failed to change to tmpdir (%d)\n"), errno); + + // init server SSL layer (default cert and key file types are PEM) + // SRCDIR is the (relative) path to the tests dir. Since we chdir()'ed into a subdirectory, we need "../" + wget_ssl_set_config_string(WGET_SSL_CA_FILE, "../" SRCDIR "/certs/x509-ca-cert.pem"); + wget_ssl_set_config_string(WGET_SSL_CERT_FILE, "../" SRCDIR "/certs/x509-server-cert.pem"); + wget_ssl_set_config_string(WGET_SSL_KEY_FILE, "../" SRCDIR "/certs/x509-server-key.pem"); + + // init HTTP server socket + http_parent_tcp=wget_tcp_init(); + wget_tcp_set_timeout(http_parent_tcp, -1); // INFINITE timeout + if (wget_tcp_listen(http_parent_tcp, "localhost", NULL, 5) != 0) + exit(1); + http_server_port = wget_tcp_get_local_port(http_parent_tcp); + + // init HTTPS server socket + https_parent_tcp=wget_tcp_init(); + wget_tcp_set_ssl(https_parent_tcp, 1); // switch SSL on + wget_tcp_set_timeout(https_parent_tcp, -1); // INFINITE timeout + if (wget_tcp_listen(https_parent_tcp, "localhost", NULL, 5) != 0) + exit(1); + https_server_port = wget_tcp_get_local_port(https_parent_tcp); + + // init FTP server socket + ftp_parent_tcp=wget_tcp_init(); + wget_tcp_set_timeout(ftp_parent_tcp, -1); // INFINITE timeout + if (wget_tcp_listen(ftp_parent_tcp, "localhost", NULL, 5) != 0) + exit(1); + ftp_server_port = wget_tcp_get_local_port(ftp_parent_tcp); + + // init FTPS server socket + ftps_parent_tcp=wget_tcp_init(); + wget_tcp_set_ssl(ftps_parent_tcp, 1); // switch SSL on + wget_tcp_set_timeout(ftps_parent_tcp, -1); // INFINITE timeout + if (wget_tcp_listen(ftps_parent_tcp, "localhost", NULL, 5) != 0) + exit(1); + ftps_server_port = wget_tcp_get_local_port(ftps_parent_tcp); + + // now replace {{port}} in the body by the actual server port + for (it = 0; it < nurls; it++) { + if (urls[it].body && (strstr(urls[it].body, "{{port}}") || strstr(urls[it].body, "{{sslport}}") + || strstr(urls[it].body, "{{ftpport}}") || strstr(urls[it].body, "{{ftpsport}}"))) + { + const char *src = urls[it].body; + char *dst = wget_malloc(strlen(src) + 1); + + urls[it].body = dst; + urls[it].body_alloc = 1; + + while (*src) { + if (*src == '{') { + if (!strncmp(src, "{{port}}", 8)) { + dst += sprintf(dst, "%d", http_server_port); + src += 8; + continue; + } + else if (!strncmp(src, "{{sslport}}", 11)) { + dst += sprintf(dst, "%d", https_server_port); + src += 11; + continue; + } + else if (!strncmp(src, "{{ftpport}}", 11)) { + dst += sprintf(dst, "%d", ftp_server_port); + src += 11; + continue; + } + else if (!strncmp(src, "{{ftpsport}}", 12)) { + dst += sprintf(dst, "%d", ftps_server_port); + src += 12; + continue; + } + } + *dst++ = *src++; + } + *dst = 0; + } + } + + // start thread for HTTP + if ((rc = wget_thread_start(&http_server_tid, _http_server_thread, http_parent_tcp, 0)) != 0) + wget_error_printf_exit(_("Failed to start HTTP server, error %d\n"), rc); + + // start thread for HTTPS + if ((rc = wget_thread_start(&https_server_tid, _http_server_thread, https_parent_tcp, 0)) != 0) + wget_error_printf_exit(_("Failed to start HTTPS server, error %d\n"), rc); + + // start thread for FTP + if ((rc = wget_thread_start(&ftp_server_tid, _ftp_server_thread, ftp_parent_tcp, 0)) != 0) + wget_error_printf_exit(_("Failed to start FTP server, error %d\n"), rc); + + // start thread for FTPS + if (ftps_implicit) { + if ((rc = wget_thread_start(&ftps_server_tid, _ftp_server_thread, ftps_parent_tcp, 0)) != 0) + wget_error_printf_exit(_("Failed to start FTP server, error %d\n"), rc); + } +} + +static void _scan_for_unexpected(const char *dirname, const wget_test_file_t *expected_files) +{ + DIR *dir; + struct dirent *dp; + struct stat st; + size_t it, dirlen = strlen(dirname); + + wget_info_printf("Entering %s\n", dirname); + + if ((dir = opendir(dirname))) { + while ((dp = readdir(dir))) { + char fname[dirlen + 1 + strlen(dp->d_name) + 1]; + + if (!strcmp(dp->d_name, ".") || !strcmp(dp->d_name, "..")) + continue; + + if (*dirname == '.' && dirname[1] == 0) + sprintf(fname, "%s", dp->d_name); + else + sprintf(fname, "%s/%s", dirname, dp->d_name); + + wget_info_printf(" - %s/%s\n", dirname, dp->d_name); + if (stat(fname, &st) == 0 && S_ISDIR(st.st_mode)) { + _scan_for_unexpected(fname, expected_files); + continue; + } + + if (expected_files) { + wget_info_printf("search %s\n", fname); + + for (it = 0; expected_files[it].name && strcmp(expected_files[it].name, fname); it++); + + if (!expected_files[it].name) + wget_error_printf_exit(_("Unexpected file %s/%s found\n"), tmpdir, fname); + } else + wget_error_printf_exit(_("Unexpected file %s/%s found\n"), tmpdir, fname); + } + + closedir(dir); + } else + wget_error_printf_exit(_("Failed to diropen %s\n"), dirname); +} + +void wget_test(int first_key, ...) +{ + const char + *request_url, + *options="", + *executable="../../src2/wget2"; + const wget_test_file_t + *expected_files = NULL, + *existing_files = NULL; + wget_buffer_t + *cmd = wget_buffer_alloc(1024); + unsigned + it; + int + key, + fd, + rc, + expected_error_code = 0; + va_list args; + + keep_tmpfiles = 0; + server_hello = "220 FTP server ready"; + + if (!request_urls) + request_urls = wget_vector_create(8,8,NULL); + + va_start (args, first_key); + for (key = first_key; key; key = va_arg(args, int)) { + switch (key) { + case WGET_TEST_REQUEST_URL: + if ((request_url = va_arg(args, const char *))) + wget_vector_add_str(request_urls, request_url); + break; + case WGET_TEST_REQUEST_URLS: + while ((request_url = va_arg(args, const char *))) + wget_vector_add_str(request_urls, request_url); + break; + case WGET_TEST_EXPECTED_ERROR_CODE: + expected_error_code = va_arg(args, int); + break; + case WGET_TEST_EXPECTED_FILES: + expected_files = va_arg(args, const wget_test_file_t *); + break; + case WGET_TEST_EXISTING_FILES: + existing_files = va_arg(args, const wget_test_file_t *); + break; + case WGET_TEST_OPTIONS: + options = va_arg(args, const char *); + break; + case WGET_TEST_KEEP_TMPFILES: + keep_tmpfiles = va_arg(args, int); + break; + case WGET_TEST_EXECUTABLE: + executable = va_arg(args, const char *); + break; + case WGET_TEST_FTP_SERVER_HELLO: + server_hello = va_arg(args, const char *); + break; + default: + wget_error_printf_exit(_("Unknown option %d [%s]\n"), key, options); + } + } + + // clean directory + wget_buffer_printf2(cmd, "../%s", tmpdir); + _empty_directory(cmd->data); + + // create files + if (existing_files) { + for (it = 0; existing_files[it].name; it++) { + if ((fd = open(existing_files[it].name, O_CREAT|O_WRONLY|O_TRUNC, 0644)) != -1) { + ssize_t nbytes = write(fd, existing_files[it].content, strlen(existing_files[it].content)); + close(fd); + + if (nbytes != (ssize_t)strlen(existing_files[it].content)) + wget_error_printf_exit(_("Failed to write %zu bytes to file %s/%s [%s]\n"), + strlen(existing_files[it].content), tmpdir, existing_files[it].name, options); + + if (existing_files[it].timestamp) { + // take the old utime() instead of utimes() + if (utime(existing_files[it].name, &(struct utimbuf){ 0, existing_files[it].timestamp })) + wget_error_printf_exit(_("Failed to set mtime of %s/%s [%s]\n"), + tmpdir, existing_files[it].name, options); + } + + } else { + wget_error_printf_exit(_("Failed to write open file %s/%s [%s] (%d,%s)\n"), + tmpdir, *existing_files[it].name == '/' ? existing_files[it].name + 1 : existing_files[it].name , options, + errno, strerror(errno)); + } + } + } + + const char *valgrind = getenv("VALGRIND_TESTS"); + if (!valgrind || !*valgrind || !strcmp(valgrind, "0")) { + wget_buffer_printf2(cmd, "%s %s", executable, options); + } else if (!strcmp(valgrind, "1")) { + wget_buffer_printf2(cmd, "valgrind --error-exitcode=301 --leak-check=yes --show-reachable=yes --track-origins=yes %s %s", executable, options); + } else + wget_buffer_printf2(cmd, "%s %s %s", valgrind, executable, options); + + for (it = 0; it < (size_t)wget_vector_size(request_urls); it++) { + wget_buffer_printf_append2(cmd, " 'http://localhost:%d/%s'", + http_server_port, (char *)wget_vector_get(request_urls, it)); + } +// for (it = 0; it < (size_t)wget_vector_size(ftp_files); it++) { +// wget_buffer_printf_append2(cmd, " 'ftp://localhost:%d/%s'", +// ftp_server_port, (char *)wget_vector_get(ftp_files, it)); +// } + wget_buffer_strcat(cmd, " 2>&1"); + + wget_error_printf("\n Testing '%s'\n", cmd->data); + rc = system(cmd->data); + +#if defined(_WIN32) || defined(_WIN64) + if (rc) { + wget_error_printf_exit(_("Failed to execute command (%d)\n"), errno); + }/* else { + if ((fp = fopen("exit_code", "r"))) { + if (fscanf(fp, "%d", &rc) != 1) + wget_error_printf_exit(_("Failed to fetch exit code\n")); + else if (rc != expected_error_code) { + wget_error_printf_exit(_("Unexpected error code %d, expected %d [%s]\n"), + rc, expected_error_code, options); + fclose(fp); + } else + wget_error_printf_exit(_("Failed to execute command (%d)\n"), errno); + } + unlink("exit_code"); */ +#else + if (!WIFEXITED(rc)) { + wget_error_printf_exit(_("Unexpected error code %d, expected %d [%s]\n"), rc, expected_error_code, options); + } + else if (WEXITSTATUS(rc) != expected_error_code) { + wget_error_printf_exit(_("Unexpected error code %d, expected %d [%s]\n"), + WEXITSTATUS(rc), expected_error_code, options); + } +#endif + + if (expected_files) { + for (it = 0; expected_files[it].name; it++) { + struct stat st; + + if (stat(expected_files[it].name, &st) != 0) + wget_error_printf_exit(_("Missing expected file %s/%s [%s]\n"), tmpdir, expected_files[it].name, options); + + if (expected_files[it].content) { + char content[st.st_size]; + + if ((fd = open(expected_files[it].name, O_RDONLY)) != -1) { + ssize_t nbytes = read(fd, content, st.st_size); + close(fd); + + if (nbytes != st.st_size) + wget_error_printf_exit(_("Failed to read %lld bytes from file %s/%s [%s]\n"), + (long long)st.st_size, tmpdir, expected_files[it].name, options); + + if (strlen(expected_files[it].content) != (size_t)nbytes || memcmp(expected_files[it].content, content, nbytes) != 0) + wget_error_printf_exit(_("Unexpected content in %s [%s]\n"), expected_files[it].name, options); + } + } + + if (expected_files[it].timestamp && st.st_mtime != expected_files[it].timestamp) + wget_error_printf_exit(_("Unexpected timestamp %s/%s [%s]\n"), tmpdir, expected_files[it].name, options); + } + } + + // look if there are unexpected files in our working dir + _scan_for_unexpected(".", expected_files); + + wget_vector_clear(request_urls); + wget_buffer_free(&cmd); + + // system("ls -la"); +} + +int wget_test_get_http_server_port(void) +{ + return http_server_port; +} + +int wget_test_get_https_server_port(void) +{ + return https_server_port; +} + +int wget_test_get_ftp_server_port(void) +{ + return ftp_server_port; +} + +int wget_test_get_ftps_server_port(void) +{ + return ftps_server_port; +} diff --git a/tests2/libtest.h b/tests2/libtest.h new file mode 100644 index 00000000..4da7c1d4 --- /dev/null +++ b/tests2/libtest.h @@ -0,0 +1,132 @@ +/* + * Copyright(c) 2013-2014 Tim Ruehsen + * + * This file is part of libwget. + * + * Libwget is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Libwget is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with libwget. If not, see <http://www.gnu.org/licenses/>. + * + * + * Test suite function library header + * + * Changelog + * 10.03.2013 Tim Ruehsen created + * + * Test suite function library + * + * To create the X.509 stuff, I followed the instructions at + * gnutls.org/manual/html_node/gnutls_002dserv-Invocation.html + * + */ + +#ifndef _LIBWGET_LIBTEST_H +#define _LIBWGET_LIBTEST_H + +#include <libwget.h> + +#ifdef __cplusplus +extern "C" { +#endif + +// defines for wget_test_start_http_server() +#define WGET_TEST_EXPECTED_REQUEST_HEADER 1001 +#define WGET_TEST_RESPONSE_URLS 1002 +#define WGET_TEST_FTP_IO_UNORDERED 1003 +#define WGET_TEST_FTP_IO_ORDERED 1004 +#define WGET_TEST_FTP_SERVER_HELLO 1005 +#define WGET_TEST_FTPS_IMPLICIT 1006 + +// defines for wget_test() +#define WGET_TEST_REQUEST_URL 2001 +#define WGET_TEST_OPTIONS 2002 +#define WGET_TEST_EXPECTED_ERROR_CODE 2003 +#define WGET_TEST_EXPECTED_FILES 2004 +#define WGET_TEST_EXISTING_FILES 2005 +#define WGET_TEST_KEEP_TMPFILES 2006 +#define WGET_TEST_REQUEST_URLS 2007 +#define WGET_TEST_EXECUTABLE 2008 + +#define countof(a) (sizeof(a)/sizeof(*(a))) + +G_GNUC_WGET_UNUSED static const char *WGET_TEST_SOME_HTML_BODY = "\ +<html>\n\ +<head>\n\ + <title>The Title</title>\n\ +</head>\n\ +<body>\n\ + <p>\n\ + Some text\n\ + </p>\n\ +</body>\n\ +</html>\n"; + +typedef struct { + const char * + name; + const char * + content; + time_t + timestamp; +} wget_test_file_t; + +typedef struct { + const char * + name; + const char * + code; + const char * + body; + const char * + headers[10]; + const char * + request_headers[10]; + time_t + modified; + char + body_alloc; // if body has been allocated internally (and need to be freed on exit) + + // auth fields + const char * + auth_method; + const char * + auth_username; + const char * + auth_password; +} wget_test_url_t; + +typedef struct { + const char * + in; + const char * + out; + wget_test_url_t * + send_url; +} wget_test_ftp_io_t; + +void wget_test_stop_server(void); +void wget_test_start_server(int first_key, ...); +void wget_test(int first_key, ...); +int wget_test_get_http_server_port(void) G_GNUC_WGET_PURE; +int wget_test_get_https_server_port(void) G_GNUC_WGET_PURE; +int wget_test_get_ftp_server_port(void) G_GNUC_WGET_PURE; +int wget_test_get_ftps_server_port(void) G_GNUC_WGET_PURE; + +#if defined(__clang__) || __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 5) +# pragma GCC diagnostic ignored "-Wmissing-field-initializers" +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* _LIBWGET_LIBTEST_H */ diff --git a/tests2/stringmap_perf.c b/tests2/stringmap_perf.c new file mode 100644 index 00000000..dda18c0e --- /dev/null +++ b/tests2/stringmap_perf.c @@ -0,0 +1,128 @@ +/* + * Copyright(c) 2012 Tim Ruehsen + * + * This file is part of MGet. + * + * Wget is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Wget is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Wget. If not, see <http://www.gnu.org/licenses/>. + * + * + * testing performance of hashmap/stringmap routines + * + * Changelog + * 06.07.2012 Tim Ruehsen created + * + */ + +#if HAVE_CONFIG_H +# include <config.h> +#endif + +#include <stdio.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <unistd.h> +#include <fcntl.h> +#include <ctype.h> +#include <string.h> +#ifdef HAVE_MMAP +# include <sys/mman.h> +#endif +#include <errno.h> + +#include <libwget.h> + +static int G_GNUC_WGET_NONNULL_ALL _print_word(G_GNUC_WGET_UNUSED void *ctx, const char *word) +{ + printf("%s\n", word); + return 0; +} + +int main(int argc, const char *const *argv) +{ + int fd, it, unique = 0, duple = 0; + char *buf, *word, *end; + size_t length; + struct stat st; + wget_stringmap_t *map = wget_stringmap_create(1024); + + for (it = 1; it < argc; it++) { + if ((fd = open(argv[it], O_RDONLY)) == -1) { + fprintf(stderr, "Failed to read open %s\n", argv[it]); + continue; + } + + if (fstat(fd, &st)) { + fprintf(stderr, "Failed to stat %s\n", argv[it]); + close(fd); + continue; + } + + length = st.st_size; + +#ifdef HAVE_MMAP + if (!(buf = mmap(NULL, length + 1, PROT_READ|PROT_WRITE, MAP_PRIVATE, fd, 0))) { + fprintf(stderr, "Failed to mmap %s (%d)\n", argv[it], errno); + close(fd); + continue; + } +#else + if (!(buf = xmalloc(length + 1)) || read(fd, buf, length) != (signed)length) { + fprintf(stderr, "Failed to read %s (%d)\n", argv[it], errno); + close(fd); + continue; + } +#endif + + buf[length] = 0; + + for (word = buf; *word; word = end) { + while (*word && !isalnum(*word)) word++; + for (end = word; *end && isalnum(*end);) end++; + if (word != end) { + char c = *end; + *end = 0; + +/* if (stringmap_get(map, word)) { + duple++; + } else { + stringmap_put_ident_noalloc(map, strndup(word, end - word)); + unique++; + } +*/ + if (wget_stringmap_put(map, word, NULL, 0)) + duple++; + else + unique++; + + *end = c; + } + } + +#ifdef HAVE_MMAP + munmap(buf, length); +#else + free(buf); +#endif + close(fd); + } + + printf("read %u words, %u uniques, %u doubles\n", unique + duple, unique, duple); + + // const void *keys = stringmap_get_keys(map); + wget_stringmap_browse(map, (int(*)(void *, const char *, void *))_print_word, NULL); + + wget_stringmap_free(&map); + + return 0; +} diff --git a/tests2/test--accept.c b/tests2/test--accept.c new file mode 100644 index 00000000..999e15d6 --- /dev/null +++ b/tests2/test--accept.c @@ -0,0 +1,270 @@ +/* + * Copyright(c) 2013 Tim Ruehsen + * + * This file is part of libwget. + * + * Libwget is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Libwget is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with libwget. If not, see <http://www.gnu.org/licenses/>. + * + * + * Testing Wget + * + * Changelog + * 08.07.2013 Tim Ruehsen created + * 02.07.2014 Tim Ruehsen added uppercase combinations of <a href...> (issue #21) + * + */ + +#if HAVE_CONFIG_H +# include <config.h> +#endif + +#include <stdlib.h> // exit() +#include "libtest.h" + +int main(void) +{ + wget_test_url_t urls[]={ + { .name = "/index.html", + .code = "200 Dontcare", + .body = + "<html><head><title>Main Page</title></head><body><p>A link to a" \ + " <A hreF=\"http://localhost:{{port}}/secondpage.html\">second page</a>." \ + " <a href=\"picture_a.jpeg\">Picture a</a>." \ + " <a href=\"picture_A.jpeg\">Picture A</a>." \ + "</p></body></html>", + .headers = { + "Content-Type: text/html", + } + }, + { .name = "/secondpage.html", + .code = "200 Dontcare", + .body = + "<html><head><title>Second Page</title></head><body><p>A link to a" \ + " <a href=\"picture_b.jpeg\">Picture b</a>." \ + " <a href=\"picture_B.JpeG\">Picture B</a>." \ + " <a href=\"picture_c.png\">Picture C</a>." \ + "</p></body></html>", + .headers = { + "Content-Type: text/html", + } + }, + { .name = "/picture_a.jpeg", + .code = "200 Dontcare", + .body = "don't care", + .headers = { "Content-Type: image/jpeg" } + }, + { .name = "/picture_A.jpeg", + .code = "200 Dontcare", + .body = "don't care", + .headers = { "Content-Type: image/jpeg" } + }, + { .name = "/picture_b.jpeg", + .code = "200 Dontcare", + .body = "don't care", + .headers = { "Content-Type: image/jpeg" } + }, + { .name = "/picture_B.JpeG", + .code = "200 Dontcare", + .body = "don't care", + .headers = { "Content-Type: image/jpeg" } + }, + { .name = "/picture_c.png", + .code = "200 Dontcare", + .body = "don't care", + .headers = { "Content-Type: image/png" } + }, + }; + + // functions won't come back if an error occurs + wget_test_start_server( + WGET_TEST_RESPONSE_URLS, &urls, countof(urls), + 0); + + // --accept using just suffixes + wget_test( + WGET_TEST_OPTIONS, "-r -nH --accept '.jpeg'", + WGET_TEST_REQUEST_URL, "index.html", + WGET_TEST_EXPECTED_ERROR_CODE, 0, + WGET_TEST_EXPECTED_FILES, &(wget_test_file_t []) { + { urls[2].name + 1, urls[2].body }, + { urls[3].name + 1, urls[3].body }, + { urls[4].name + 1, urls[4].body }, + { NULL } }, + 0); + + // --reject using just suffixes + wget_test( + WGET_TEST_OPTIONS, "-r -nH --reject '.jpeg'", + WGET_TEST_REQUEST_URL, "index.html", + WGET_TEST_EXPECTED_ERROR_CODE, 0, + WGET_TEST_EXPECTED_FILES, &(wget_test_file_t []) { + { urls[0].name + 1, urls[0].body }, + { urls[1].name + 1, urls[1].body }, + { urls[5].name + 1, urls[5].body }, + { urls[6].name + 1, urls[6].body }, + { NULL } }, + 0); + + // --accept using just suffixes and ignore case + wget_test( + WGET_TEST_OPTIONS, "-r -nH --accept '.jpeg' --ignore-case", + WGET_TEST_REQUEST_URL, "index.html", + WGET_TEST_EXPECTED_ERROR_CODE, 0, + WGET_TEST_EXPECTED_FILES, &(wget_test_file_t []) { + { urls[2].name + 1, urls[2].body }, + { urls[3].name + 1, urls[3].body }, + { urls[4].name + 1, urls[4].body }, + { urls[5].name + 1, urls[5].body }, + { NULL } }, + 0); + + // --reject using just suffixes and ignore case + wget_test( + WGET_TEST_OPTIONS, "-r -nH --reject '.jpeg' --ignore-case", + WGET_TEST_REQUEST_URL, "index.html", + WGET_TEST_EXPECTED_ERROR_CODE, 0, + WGET_TEST_EXPECTED_FILES, &(wget_test_file_t []) { + { urls[0].name + 1, urls[0].body }, + { urls[1].name + 1, urls[1].body }, + { urls[6].name + 1, urls[6].body }, + { NULL } }, + 0); + + // --accept using wildcards + wget_test( + WGET_TEST_OPTIONS, "-r -nH --accept '*.jpeg'", + WGET_TEST_REQUEST_URL, "index.html", + WGET_TEST_EXPECTED_ERROR_CODE, 0, + WGET_TEST_EXPECTED_FILES, &(wget_test_file_t []) { + { urls[2].name + 1, urls[2].body }, + { urls[3].name + 1, urls[3].body }, + { urls[4].name + 1, urls[4].body }, + { NULL } }, + 0); + + // --reject using wildcards + wget_test( + WGET_TEST_OPTIONS, "-r -nH --reject '*.jpeg'", + WGET_TEST_REQUEST_URL, "index.html", + WGET_TEST_EXPECTED_ERROR_CODE, 0, + WGET_TEST_EXPECTED_FILES, &(wget_test_file_t []) { + { urls[0].name + 1, urls[0].body }, + { urls[1].name + 1, urls[1].body }, + { urls[5].name + 1, urls[5].body }, + { urls[6].name + 1, urls[6].body }, + { NULL } }, + 0); + + // --accept using wildcards and ignore case + wget_test( + WGET_TEST_OPTIONS, "-r -nH --accept '*.jpeg' --ignore-case", + WGET_TEST_REQUEST_URL, "index.html", + WGET_TEST_EXPECTED_ERROR_CODE, 0, + WGET_TEST_EXPECTED_FILES, &(wget_test_file_t []) { + { urls[2].name + 1, urls[2].body }, + { urls[3].name + 1, urls[3].body }, + { urls[4].name + 1, urls[4].body }, + { urls[5].name + 1, urls[5].body }, + { NULL } }, + 0); + + // --reject using wildcards and ignore case + wget_test( + WGET_TEST_OPTIONS, "-r -nH --reject '*.jpeg' --ignore-case", + WGET_TEST_REQUEST_URL, "index.html", + WGET_TEST_EXPECTED_ERROR_CODE, 0, + WGET_TEST_EXPECTED_FILES, &(wget_test_file_t []) { + { urls[0].name + 1, urls[0].body }, + { urls[1].name + 1, urls[1].body }, + { urls[6].name + 1, urls[6].body }, + { NULL } }, + 0); + + // --accept using wildcards + wget_test( + WGET_TEST_OPTIONS, "-r -nH --accept '*picture*'", + WGET_TEST_REQUEST_URL, "index.html", + WGET_TEST_EXPECTED_ERROR_CODE, 0, + WGET_TEST_EXPECTED_FILES, &(wget_test_file_t []) { + { urls[2].name + 1, urls[2].body }, + { urls[3].name + 1, urls[3].body }, + { urls[4].name + 1, urls[4].body }, + { urls[5].name + 1, urls[5].body }, + { urls[6].name + 1, urls[6].body }, + { NULL } }, + 0); + + // --reject using wildcards + wget_test( + WGET_TEST_OPTIONS, "-r -nH --reject '*picture*'", + WGET_TEST_REQUEST_URL, "index.html", + WGET_TEST_EXPECTED_ERROR_CODE, 0, + WGET_TEST_EXPECTED_FILES, &(wget_test_file_t []) { + { urls[0].name + 1, urls[0].body }, + { urls[1].name + 1, urls[1].body }, + { NULL } }, + 0); + + // --accept using wildcards + wget_test( + WGET_TEST_OPTIONS, "-r -nH --accept '*picture_[ab]*'", + WGET_TEST_REQUEST_URL, "index.html", + WGET_TEST_EXPECTED_ERROR_CODE, 0, + WGET_TEST_EXPECTED_FILES, &(wget_test_file_t []) { + { urls[2].name + 1, urls[2].body }, + { urls[4].name + 1, urls[4].body }, + { NULL } }, + 0); + + // --reject using wildcards + wget_test( + WGET_TEST_OPTIONS, "-r -nH --reject '*picture_[ab]*'", + WGET_TEST_REQUEST_URL, "index.html", + WGET_TEST_EXPECTED_ERROR_CODE, 0, + WGET_TEST_EXPECTED_FILES, &(wget_test_file_t []) { + { urls[0].name + 1, urls[0].body }, + { urls[1].name + 1, urls[1].body }, + { urls[3].name + 1, urls[3].body }, + { urls[5].name + 1, urls[5].body }, + { urls[6].name + 1, urls[6].body }, + { NULL } }, + 0); + + // --accept using wildcards + wget_test( + WGET_TEST_OPTIONS, "-r -nH --accept '*picture_a*' --accept '*picture_c*'", + WGET_TEST_REQUEST_URL, "index.html", + WGET_TEST_EXPECTED_ERROR_CODE, 0, + WGET_TEST_EXPECTED_FILES, &(wget_test_file_t []) { + { urls[2].name + 1, urls[2].body }, + { urls[6].name + 1, urls[6].body }, + { NULL } }, + 0); + + // --reject using wildcards + wget_test( + WGET_TEST_OPTIONS, "-r -nH --reject '*picture_a*' --reject '*picture_c*'", + WGET_TEST_REQUEST_URL, "index.html", + WGET_TEST_EXPECTED_ERROR_CODE, 0, + WGET_TEST_EXPECTED_FILES, &(wget_test_file_t []) { + { urls[0].name + 1, urls[0].body }, + { urls[1].name + 1, urls[1].body }, + { urls[3].name + 1, urls[3].body }, + { urls[4].name + 1, urls[4].body }, + { urls[5].name + 1, urls[5].body }, + { NULL } }, + 0); + + exit(0); +} diff --git a/tests2/test--follow-tags.c b/tests2/test--follow-tags.c new file mode 100644 index 00000000..99dcf1be --- /dev/null +++ b/tests2/test--follow-tags.c @@ -0,0 +1,215 @@ +/* + * Copyright(c) 2013 Tim Ruehsen + * + * This file is part of libwget. + * + * Libwget is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Libwget is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with libwget. If not, see <http://www.gnu.org/licenses/>. + * + * + * Testing Wget + * + * Changelog + * 09.09.2014 Tim Ruehsen created + * + */ + +#if HAVE_CONFIG_H +# include <config.h> +#endif + +#include <stdlib.h> // exit() +#include "libtest.h" + +int main(void) +{ + wget_test_url_t urls[]={ + { .name = "/index.html", + .code = "200 Dontcare", + .body = + "<html><head><title>Main Page</title></head><body><p>A link to a" \ + " <a href=\"secondpage.html\">second page</a>." \ + "</p></body></html>", + .headers = { + "Content-Type: text/html", + } + }, + { .name = "/secondpage.html", + .code = "200 Dontcare", + .body = + "<html><head><title>Second Page</title></head><body><p>A link to a" \ + " <a href=\"2a.jpeg\">Picture 2a</a>." \ + " <img src=\"2b.jpeg\" data-500px=\"2c.jpeg\" data-highres=\"2d.jpeg\">" \ + "</p></body></html>", + .headers = { + "Content-Type: text/html", + } + }, + { .name = "/2a.jpeg", + .code = "200 Dontcare", + .body = "pic 2a", + .headers = { "Content-Type: image/jpeg" } + }, + { .name = "/2b.jpeg", + .code = "200 Dontcare", + .body = "pic 2b", + .headers = { "Content-Type: image/jpeg" } + }, + { .name = "/2c.jpeg", + .code = "200 Dontcare", + .body = "pic 2c", + .headers = { "Content-Type: image/jpeg" } + }, + { .name = "/2d.jpeg", + .code = "200 Dontcare", + .body = "pic 2c", + .headers = { "Content-Type: image/jpeg" } + }, + }; + + // functions won't come back if an error occurs + wget_test_start_server( + WGET_TEST_RESPONSE_URLS, &urls, countof(urls), + 0); + + // without additional tags + wget_test( + WGET_TEST_OPTIONS, "-r -nH ", + WGET_TEST_REQUEST_URL, "index.html", + WGET_TEST_EXPECTED_ERROR_CODE, 0, + WGET_TEST_EXPECTED_FILES, &(wget_test_file_t []) { + { urls[0].name + 1, urls[0].body }, + { urls[1].name + 1, urls[1].body }, + { urls[2].name + 1, urls[2].body }, + { urls[3].name + 1, urls[3].body }, + { NULL } }, + 0); + + // --follow-tags single entry + wget_test( + WGET_TEST_OPTIONS, "-r -nH --follow-tags 'img/data-500px'", + WGET_TEST_REQUEST_URL, "index.html", + WGET_TEST_EXPECTED_ERROR_CODE, 0, + WGET_TEST_EXPECTED_FILES, &(wget_test_file_t []) { + { urls[0].name + 1, urls[0].body }, + { urls[1].name + 1, urls[1].body }, + { urls[2].name + 1, urls[2].body }, + { urls[3].name + 1, urls[3].body }, + { urls[4].name + 1, urls[4].body }, + { NULL } }, + 0); + + // --follow-tags single entry without attribute + wget_test( + WGET_TEST_OPTIONS, "-r -nH --follow-tags 'img'", + WGET_TEST_REQUEST_URL, "index.html", + WGET_TEST_EXPECTED_ERROR_CODE, 0, + WGET_TEST_EXPECTED_FILES, &(wget_test_file_t []) { + { urls[0].name + 1, urls[0].body }, + { urls[1].name + 1, urls[1].body }, + { urls[2].name + 1, urls[2].body }, + { urls[3].name + 1, urls[3].body }, + { urls[4].name + 1, urls[4].body }, + { urls[5].name + 1, urls[5].body }, + { NULL } }, + 0); + + // --follow-tags two entries + wget_test( + WGET_TEST_OPTIONS, "-r -nH --follow-tags 'img/data-500px,img/data-highres'", + WGET_TEST_REQUEST_URL, "index.html", + WGET_TEST_EXPECTED_ERROR_CODE, 0, + WGET_TEST_EXPECTED_FILES, &(wget_test_file_t []) { + { urls[0].name + 1, urls[0].body }, + { urls[1].name + 1, urls[1].body }, + { urls[2].name + 1, urls[2].body }, + { urls[3].name + 1, urls[3].body }, + { urls[4].name + 1, urls[4].body }, + { urls[5].name + 1, urls[5].body }, + { NULL } }, + 0); + + // --follow-tags two entries + wget_test( + WGET_TEST_OPTIONS, "-r -nH --follow-tags 'img/data-highres,img/data-500px'", + WGET_TEST_REQUEST_URL, "index.html", + WGET_TEST_EXPECTED_ERROR_CODE, 0, + WGET_TEST_EXPECTED_FILES, &(wget_test_file_t []) { + { urls[0].name + 1, urls[0].body }, + { urls[1].name + 1, urls[1].body }, + { urls[2].name + 1, urls[2].body }, + { urls[3].name + 1, urls[3].body }, + { urls[4].name + 1, urls[4].body }, + { urls[5].name + 1, urls[5].body }, + { NULL } }, + 0); + + // --ignore-tags single entry + wget_test( + WGET_TEST_OPTIONS, "-r -nH --ignore-tags 'img/src'", + WGET_TEST_REQUEST_URL, "index.html", + WGET_TEST_EXPECTED_ERROR_CODE, 0, + WGET_TEST_EXPECTED_FILES, &(wget_test_file_t []) { + { urls[0].name + 1, urls[0].body }, + { urls[1].name + 1, urls[1].body }, + { urls[2].name + 1, urls[2].body }, + { NULL } }, + 0); + + // --ignore-tags single entry without attribute + wget_test( + WGET_TEST_OPTIONS, "-r -nH --ignore-tags 'img'", + WGET_TEST_REQUEST_URL, "index.html", + WGET_TEST_EXPECTED_ERROR_CODE, 0, + WGET_TEST_EXPECTED_FILES, &(wget_test_file_t []) { + { urls[0].name + 1, urls[0].body }, + { urls[1].name + 1, urls[1].body }, + { urls[2].name + 1, urls[2].body }, + { NULL } }, + 0); + + // --ignore-tags two entries + wget_test( + WGET_TEST_OPTIONS, "-r -nH --ignore-tags 'img/src,a/href'", + WGET_TEST_REQUEST_URL, "index.html", + WGET_TEST_EXPECTED_ERROR_CODE, 0, + WGET_TEST_EXPECTED_FILES, &(wget_test_file_t []) { + { urls[0].name + 1, urls[0].body }, + { NULL } }, + 0); + + // --ignore-tags two entries + wget_test( + WGET_TEST_OPTIONS, "-r -nH --ignore-tags 'a/href,img/src'", + WGET_TEST_REQUEST_URL, "index.html", + WGET_TEST_EXPECTED_ERROR_CODE, 0, + WGET_TEST_EXPECTED_FILES, &(wget_test_file_t []) { + { urls[0].name + 1, urls[0].body }, + { NULL } }, + 0); + + // --ignore-tags and --follow-tags combined + wget_test( + WGET_TEST_OPTIONS, "-r -nH --ignore-tags 'img/src' --follow-tags='img/data-500px'", + WGET_TEST_REQUEST_URL, "index.html", + WGET_TEST_EXPECTED_ERROR_CODE, 0, + WGET_TEST_EXPECTED_FILES, &(wget_test_file_t []) { + { urls[0].name + 1, urls[0].body }, + { urls[1].name + 1, urls[1].body }, + { urls[2].name + 1, urls[2].body }, + { urls[4].name + 1, urls[4].body }, + { NULL } }, + 0); + + exit(0); +} diff --git a/tests2/test--page-requisites.c b/tests2/test--page-requisites.c new file mode 100644 index 00000000..a6e0d876 --- /dev/null +++ b/tests2/test--page-requisites.c @@ -0,0 +1,105 @@ +/* + * Copyright(c) 2013 Tim Ruehsen + * + * This file is part of libwget. + * + * Libwget is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Libwget is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with libwget. If not, see <http://www.gnu.org/licenses/>. + * + * + * Testing Wget + * + * Changelog + * 27.05.2014 Tim Ruehsen created + * + */ + +#if HAVE_CONFIG_H +# include <config.h> +#endif + +#include <stdlib.h> // exit() +#include "libtest.h" + +int main(void) +{ + wget_test_url_t urls[]={ + { .name = "/index.html", + .code = "200 Dontcare", + .body = + "<html><head><title>Main Page</title></head><body><p>A link to a" \ + " <a href=\"http://localhost:{{port}}/secondpage.html\">second page</a>." \ + " Hey, a picture <img src=\"picture.png\"/>." \ + "</p></body></html>", + .headers = { + "Content-Type: text/html", + } + }, + { .name = "/secondpage.html", + .code = "200 Dontcare", + .body = + "<html><head><title>Second Page</title></head><body><p>A link to a" \ + " <a href=\"http://localhost:{{port}}/thirdpage.html\">third page</a>." \ + " Also, a <a href=\"http://localhost:{{port}}/nonexistent\">broken link</a>." \ + "</p></body></html>", + .headers = { + "Content-Type: text/html", + "Content-Disposition: attachment; filename=\"filename.html\"", + } + }, + { .name = "/thirdpage.html", + .code = "200 Dontcare", + .body = + "<html><head><title>Third Page</title></head><body><p>A link to a" \ + " <a href=\"http://localhost:{{port}}/dummy.txt\">text file</a>." \ + " Also, a <a href=\"http://localhost:{{port}}/againnonexistent\">broken link</a>." \ + "</p></body></html>", + .headers = { + "Content-Type: text/html", + } + }, + { .name = "/picture.png", + .code = "200 Dontcare", + .body = "PNG data", + .headers = { + "Content-Type: image/png", + } + }, + { .name = "/dummy.txt", + .code = "200 Dontcare", + .body = "What ever", + .headers = { + "Content-Type: text/plain", + } + }, + }; + + // functions won't come back if an error occurs + wget_test_start_server( + WGET_TEST_RESPONSE_URLS, &urls, countof(urls), + 0); + + // test--page-requisites + wget_test( +// WGET_TEST_KEEP_TMPFILES, 1, + WGET_TEST_OPTIONS, "--page-requisites", + WGET_TEST_REQUEST_URL, "index.html", + WGET_TEST_EXPECTED_ERROR_CODE, 0, + WGET_TEST_EXPECTED_FILES, &(wget_test_file_t []) { + { "localhost/index.html", urls[0].body }, + { "localhost/picture.png", urls[3].body }, + { NULL } }, + 0); + + exit(0); +} diff --git a/tests2/test--post-file.c b/tests2/test--post-file.c new file mode 100644 index 00000000..0004ddf1 --- /dev/null +++ b/tests2/test--post-file.c @@ -0,0 +1,47 @@ +/* + * Copyright(c) 2013 Tim Ruehsen + * + * This file is part of libwget. + * + * Libwget is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Libwget is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with libwget. If not, see <http://www.gnu.org/licenses/>. + * + * + * Testing Wget + * + * Changelog + * 15.07.2013 Tim Ruehsen created + * + */ + +#if HAVE_CONFIG_H +# include <config.h> +#endif + +#include <stdlib.h> // exit() +#include "libtest.h" + +int main(void) +{ + // functions won't come back if an error occurs + wget_test_start_server(0); + + // test-i + wget_test( + WGET_TEST_OPTIONS, "-d --post-file=nofile", + WGET_TEST_REQUEST_URL, "", + WGET_TEST_EXPECTED_ERROR_CODE, 3, // fails with older Wget (<= 1.14) + 0); + + exit(0); +} diff --git a/tests2/test--spider-r.c b/tests2/test--spider-r.c new file mode 100644 index 00000000..3a17a656 --- /dev/null +++ b/tests2/test--spider-r.c @@ -0,0 +1,103 @@ +/* + * Copyright(c) 2013 Tim Ruehsen + * + * This file is part of libwget. + * + * Libwget is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Libwget is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with libwget. If not, see <http://www.gnu.org/licenses/>. + * + * + * Testing Wget + * + * Changelog + * 15.07.2013 Tim Ruehsen created + * + */ + +#if HAVE_CONFIG_H +# include <config.h> +#endif + +#include <stdlib.h> // exit() +#include "libtest.h" + +int main(void) +{ + wget_test_url_t urls[]={ + { .name = "/index.html", + .code = "200 Dontcare", + .body = + "<html><head><title>Main Page</title></head><body><p>A link to a" \ + " <a href=\"http://localhost:{{port}}/secondpage.html\">second page</a>." \ + " Also, a <a href=\"http://localhost:{{port}}/nonexistent\">broken link</a>." \ + "</p></body></html>", + .headers = { + "Content-Type: text/html", + } + }, + { .name = "/secondpage.html", + .code = "200 Dontcare", + .body = + "<html><head><title>Second Page</title></head><body><p>A link to a" \ + " <a href=\"http://localhost:{{port}}/thirdpage.html\">third page</a>." \ + " Also, a <a href=\"http://localhost:{{port}}/nonexistent\">broken link</a>." \ + "</p></body></html>", + .headers = { + "Content-Type: text/html", + "Content-Disposition: attachment; filename=\"filename.html\"", + } + }, + { .name = "/thirdpage.html", + .code = "200 Dontcare", + .body = + "<html><head><title>Third Page</title></head><body><p>A link to a" \ + " <a href=\"http://localhost:{{port}}/dummy.txt\">text file</a>." \ + " Also, a <a href=\"http://localhost:{{port}}/againnonexistent\">broken link</a>." \ + "</p></body></html>", + .headers = { + "Content-Type: text/html", + } + }, + { .name = "/dummy.txt", + .code = "200 Dontcare", + .body = "What ever", + .headers = { + "Content-Type: text/plain", + } + }, + }; + + // functions won't come back if an error occurs + wget_test_start_server( + WGET_TEST_RESPONSE_URLS, &urls, countof(urls), + 0); + + // test--spider-r-HTTP-Content-Disposition + wget_test( +// WGET_TEST_KEEP_TMPFILES, 1, + WGET_TEST_OPTIONS, "--spider -r", + WGET_TEST_REQUEST_URL, "index.html", + WGET_TEST_EXPECTED_ERROR_CODE, 8, + 0); + + // test--spider-r + urls[1].headers[1] = NULL; + wget_test( +// WGET_TEST_KEEP_TMPFILES, 1, + WGET_TEST_OPTIONS, "--spider -r", + WGET_TEST_REQUEST_URL, "index.html", + WGET_TEST_EXPECTED_ERROR_CODE, 8, + 0); + + exit(0); +} diff --git a/tests2/test-E-k.c b/tests2/test-E-k.c new file mode 100644 index 00000000..2a45cf83 --- /dev/null +++ b/tests2/test-E-k.c @@ -0,0 +1,90 @@ +/* + * Copyright(c) 2013 Tim Ruehsen + * + * This file is part of libwget. + * + * Libwget is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Libwget is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with libwget. If not, see <http://www.gnu.org/licenses/>. + * + * + * Testing Wget + * + * Changelog + * 15.07.2013 Tim Ruehsen created + * + */ + +#if HAVE_CONFIG_H +# include <config.h> +#endif + +#include <stdlib.h> // exit() +#include "libtest.h" + +int main(void) +{ + wget_test_url_t urls[]={ + { .name = "/index.php", + .code = "200 Dontcare", + .body = + "<html><head><title>Main Page</title></head><body><p>A link to a" \ + " <a href=\"http://localhost:{{port}}/subpage.php\">second page</a>." \ + "</p></body></html>", + .headers = { + "Content-Type: text/html", + } + }, + { .name = "/subpage.php", + .code = "200 Dontcare", + .body = "<html><head><title>Sub Page</title></head><body>Some Text</body></html>", + .headers = { + "Content-Type: text/html", + } + }, + }; + + const char *mainpagemangled = + "<html><head><title>Main Page</title></head><body><p>A link to a" \ + " <a href=\"subpage.php.html\">second page</a>." \ + "</p></body></html>"; + + // functions won't come back if an error occurs + wget_test_start_server( + WGET_TEST_RESPONSE_URLS, &urls, countof(urls), + 0); + + // test-E-k + wget_test( + WGET_TEST_OPTIONS, "-r -nd -E -k", + WGET_TEST_REQUEST_URL, "index.php", + WGET_TEST_EXPECTED_ERROR_CODE, 0, + WGET_TEST_EXPECTED_FILES, &(wget_test_file_t []) { + { "index.php.html", mainpagemangled }, + { "subpage.php.html", urls[1].body }, + { NULL } }, + 0); + + // test-E-k-K + wget_test( + WGET_TEST_OPTIONS, "-r -nd -E -k -K", + WGET_TEST_REQUEST_URL, "index.php", + WGET_TEST_EXPECTED_ERROR_CODE, 0, + WGET_TEST_EXPECTED_FILES, &(wget_test_file_t []) { + { "index.php.html", mainpagemangled }, + { "index.php.orig", urls[0].body }, + { "subpage.php.html", urls[1].body }, + { NULL } }, + 0); + + exit(0); +} diff --git a/tests2/test-auth-basic.c b/tests2/test-auth-basic.c new file mode 100644 index 00000000..bc8fc35b --- /dev/null +++ b/tests2/test-auth-basic.c @@ -0,0 +1,70 @@ +/* + * Copyright(c) 2013 Tim Ruehsen + * + * This file is part of libwget. + * + * Libwget is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Libwget is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with libwget. If not, see <http://www.gnu.org/licenses/>. + * + * + * Testing Wget + * + * Changelog + * 08.07.2013 Tim Ruehsen created + * + */ + +#if HAVE_CONFIG_H +# include <config.h> +#endif + +#include <stdlib.h> // exit() +#include <string.h> // strlen() +#include "libtest.h" + +#define username "my_username" +#define password "my_password" + +int main(void) +{ + wget_test_url_t urls[] = { + { .name = "/needs-auth.txt", + .auth_method = "Basic", + .auth_username = username, + .auth_password = password, + .code = "200 Dontcare", + .body = "You are authenticated.", + .headers = { + "Content-Type: text/plain", + } + } + }; + + // functions won't come back if an error occurs + wget_test_start_server( + WGET_TEST_RESPONSE_URLS, &urls, countof(urls), + 0); + + // test-auth-basic + wget_test( +// WGET_TEST_KEEP_TMPFILES, 1, + WGET_TEST_OPTIONS, "-d --user=" username " --password=" password, + WGET_TEST_REQUEST_URL, urls[0].name + 1, + WGET_TEST_EXPECTED_ERROR_CODE, 0, + WGET_TEST_EXPECTED_FILES, &(wget_test_file_t []) { + { urls[0].name + 1, urls[0].body }, + { NULL } }, + 0); + + exit(0); +} diff --git a/tests2/test-directory-clash.c b/tests2/test-directory-clash.c new file mode 100644 index 00000000..24db3fcb --- /dev/null +++ b/tests2/test-directory-clash.c @@ -0,0 +1,107 @@ +/* + * Copyright(c) 2014 Tim Ruehsen + * + * This file is part of libwget. + * + * Libwget is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Libwget is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with libwget. If not, see <http://www.gnu.org/licenses/>. + * + * + * Testing file/directory ambiguity + * + * Changelog + * 19.09.2014 Tim Ruehsen created + * + */ + +#if HAVE_CONFIG_H +# include <config.h> +#endif + +#include <stdlib.h> // exit() +#include "libtest.h" + +int main(void) +{ + wget_test_url_t urls[]={ + { .name = "/index.html", + .code = "200 Dontcare", + .body = + "<html><head><title>Main Page</title></head><body><p>Moin" \ + " <a href=\"http://localhost:{{port}}/subdir\">File with same name as directory</a>." \ + " <a href=\"subdir/\">Directory again</a>." \ + " <a href=\"subdir/index.html\">File in directory</a>." \ + "</p></body></html>", + .headers = { + "Content-Type: text/html", + } + }, + { .name = "/index2.html", + .code = "200 Dontcare", + .body = + "<html><head><title>Main Page</title></head><body><p>Moin" \ + " <a href=\"subdir/\">Directory</a>." \ + " <a href=\"subdir/index.html\">File in directory</a>." \ + " <a href=\"http://localhost:{{port}}/subdir\">File with same name as directory</a>." \ + "</p></body></html>", + .headers = { + "Content-Type: text/html", + } + }, + { .name = "/subdir", + .code = "200 Dontcare", + .body = + "<html><head><title>Subdir Page 1</title></head><body><p>Hello 1</p></body></html>", + .headers = { + "Content-Type: text/html", + } + }, + { .name = "/subdir/index.html", + .code = "200 Dontcare", + .body = + "<html><head><title>Second Page</title></head><body><p>Hello 2</p></body></html>", + .headers = { + "Content-Type: text/html", + } + }, + }; + + // functions won't come back if an error occurs + wget_test_start_server( + WGET_TEST_RESPONSE_URLS, &urls, countof(urls), + 0); + + wget_test( + WGET_TEST_OPTIONS, "-r -nH", + WGET_TEST_REQUEST_URL, "index.html", + WGET_TEST_EXPECTED_ERROR_CODE, 0, + WGET_TEST_EXPECTED_FILES, &(wget_test_file_t []) { + { urls[0].name + 1, urls[0].body }, + { urls[3].name + 1, urls[3].body }, + { "subdir.1", urls[2].body, 0 }, // filename / directory clash appends .x to the file + { NULL } }, + 0); + + wget_test( + WGET_TEST_OPTIONS, "-r -nH", + WGET_TEST_REQUEST_URL, "index2.html", + WGET_TEST_EXPECTED_ERROR_CODE, 0, + WGET_TEST_EXPECTED_FILES, &(wget_test_file_t []) { + { urls[1].name + 1, urls[1].body }, + { urls[3].name + 1, urls[3].body }, + { "subdir.1", urls[2].body, 0 }, // filename / directory clash appends .x to the file + { NULL } }, + 0); + + exit(0); +} diff --git a/tests2/test-ftp.c b/tests2/test-ftp.c new file mode 100644 index 00000000..5f87218c --- /dev/null +++ b/tests2/test-ftp.c @@ -0,0 +1,122 @@ +/* + * Copyright(c) 2013 Tim Ruehsen + * + * This file is part of libwget. + * + * Libwget is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Libwget is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with libwget. If not, see <http://www.gnu.org/licenses/>. + * + * + * Testing Wget + * + * Changelog + * 08.07.2015 Tim Ruehsen created + * + */ + +#if HAVE_CONFIG_H +# include <config.h> +#endif + +#include <stdlib.h> // exit() +#include "libtest.h" + +int main(void) +{ + wget_test_url_t urls[]={ + { .name = "info.txt", + .body = "Dummy file content" + }, + { .name = ".listing", + .body = +"drwxr-xr-x 9 ftp ftp 4096 Aug 14 2013 .\r\n" +"drwxr-xr-x 9 ftp ftp 4096 Aug 14 2013 ..\r\n" +"lrw-r--r-- 1 ftp ftp 16 Jan 12 2013 dir2 -> dir1\r\n" +"drwxr-xr-x 8 ftp ftp 4096 Jul 8 15:37 dir1\r\n" +"-rw-r--r-- 1 ftp ftp 245 Jul 1 2013 info.txt\r\n" + }, + }; + wget_test_ftp_io_t io[]={ + { .in = "USER anonymous", + .out = "331 Anonymous login ok" + }, + { .in = "PASS -wget@", + .out = "230- Hello\r\n and good night\r\n\r\n230 Access granted" + }, + { .in = "SYST", + .out = "215 UNIX Type: L8" + }, + { .in = "PWD", + .out = "257 \"/\" is the current directory" + }, + { .in = "TYPE I", + .out = "200 Type set to I" + }, + { .in = "PASV", + .out = "227 Entering Passive Mode {{pasvdata}}." + }, + { .in = "EPSV 2", + .out = "229 Entering Passive Mode {{pasvdata}}." + }, + { .in = "LIST -a", + .out = "150 Opening BINARY mode data connection for file list", + .send_url = &urls[1] + }, + { .in = "RETR info.txt", + .out = "150 Opening BINARY mode data connection", + .send_url = &urls[0] + }, + }; + + // functions won't come back if an error occurs + wget_test_start_server( + WGET_TEST_RESPONSE_URLS, &urls, countof(urls), + WGET_TEST_FTP_IO_UNORDERED, &io, countof(io), + 0); + + char options[128]; + + // without -O/dev/null Wget generates HTML output from the listing + snprintf(options, sizeof(options), + "-d --tries=1 --no-remove-listing -O/dev/null ftp://localhost:%d", + wget_test_get_ftp_server_port()); + + // test downloading the top directory content + wget_test( +// WGET_TEST_KEEP_TMPFILES, 1, + WGET_TEST_OPTIONS, options, + WGET_TEST_EXECUTABLE, "wget", + WGET_TEST_EXPECTED_ERROR_CODE, 0, + WGET_TEST_EXPECTED_FILES, &(wget_test_file_t []) { + { urls[1].name, urls[1].body }, + { NULL } }, + 0); + + // without -O/dev/null Wget generates HTML output from the listing + snprintf(options, sizeof(options), + "-d ftp://localhost:%d/info.txt", + wget_test_get_ftp_server_port()); + + // test downloading a file + wget_test( +// WGET_TEST_KEEP_TMPFILES, 1, + WGET_TEST_OPTIONS, options, + WGET_TEST_EXECUTABLE, "wget", + WGET_TEST_EXPECTED_ERROR_CODE, 0, + WGET_TEST_EXPECTED_FILES, &(wget_test_file_t []) { + { urls[0].name, urls[0].body }, + { NULL } }, + 0); + + exit(0); +} diff --git a/tests2/test-ftps.c b/tests2/test-ftps.c new file mode 100644 index 00000000..124b347a --- /dev/null +++ b/tests2/test-ftps.c @@ -0,0 +1,103 @@ +/* + * Copyright(c) 2013 Tim Ruehsen + * + * This file is part of libwget. + * + * Libwget is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Libwget is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with libwget. If not, see <http://www.gnu.org/licenses/>. + * + * + * Testing Wget + * + * Changelog + * 08.07.2015 Tim Ruehsen created + * + */ + +#if HAVE_CONFIG_H +# include <config.h> +#endif + +#include <stdlib.h> // exit() +#include "libtest.h" + +int main(void) +{ + wget_test_url_t urls[]={ + { .name = "info.txt", + .body = "Dummy file content" + }, + { .name = ".listing", + .body = +"drwxr-xr-x 9 ftp ftp 4096 Aug 14 2013 .\r\n" +"drwxr-xr-x 9 ftp ftp 4096 Aug 14 2013 ..\r\n" +"lrw-r--r-- 1 ftp ftp 16 Jan 12 2013 dir2 -> dir1\r\n" +"drwxr-xr-x 8 ftp ftp 4096 Jul 8 15:37 dir1\r\n" +"-rw-r--r-- 1 ftp ftp 245 Jul 1 2013 info.txt\r\n" + }, + }; + wget_test_ftp_io_t io[]={ + { .in = "USER anonymous", + .out = "331 Anonymous login ok" + }, + { .in = "PASS -wget@", + .out = "230- Hello\r\n and good night\r\n\r\n230 Access granted" + }, + { .in = "SYST", + .out = "215 UNIX Type: L8" + }, + { .in = "PWD", + .out = "257 \"/\" is the current directory" + }, + { .in = "TYPE I", + .out = "200 Type set to I" + }, + { .in = "PASV", + .out = "227 Entering Passive Mode {{pasvdata}}." + }, + { .in = "EPSV 2", + .out = "229 Entering Passive Mode {{pasvdata}}." + }, + { .in = "LIST -a", + .out = "150 Opening BINARY mode data connection for file list", + .send_url = &urls[1] + }, + }; + + // functions won't come back if an error occurs + wget_test_start_server( + WGET_TEST_RESPONSE_URLS, &urls, countof(urls), + WGET_TEST_FTP_IO_UNORDERED, &io, countof(io), + WGET_TEST_FTPS_IMPLICIT, 1, // use TLS connections right away, no AUTH + 0); + + char options[128]; + + // without -O/dev/null Wget generates HTML output from the listing + snprintf(options, sizeof(options), + "-d --tries=1 --no-remove-listing -O/dev/null ftp://localhost:%d", + wget_test_get_ftp_server_port()); + + // test-ftp + wget_test( +// WGET_TEST_KEEP_TMPFILES, 1, + WGET_TEST_OPTIONS, options, + WGET_TEST_EXECUTABLE, "wget", + WGET_TEST_EXPECTED_ERROR_CODE, 0, + WGET_TEST_EXPECTED_FILES, &(wget_test_file_t []) { + { urls[1].name, urls[1].body }, + { NULL } }, + 0); + + exit(0); +} diff --git a/tests2/test-i-http.c b/tests2/test-i-http.c new file mode 100644 index 00000000..d648a826 --- /dev/null +++ b/tests2/test-i-http.c @@ -0,0 +1,94 @@ +/* + * Copyright(c) 2013 Tim Ruehsen + * + * This file is part of libwget. + * + * Libwget is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Libwget is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with libwget. If not, see <http://www.gnu.org/licenses/>. + * + * + * Testing Wget + * + * Changelog + * 08.07.2013 Tim Ruehsen created + * + */ + +#if HAVE_CONFIG_H +# include <config.h> +#endif + +#include <stdlib.h> // exit() +#include "libtest.h" + +int main(void) +{ + wget_test_url_t urls[]={ + { .name = "/urls.txt", + .code = "200 Dontcare", + .body = "http://localhost:{{port}}/page1.html\nhttp://localhost:{{port}}/page2.html\n", + .headers = { + "Content-Type: text/plain", + } + }, + { .name = "/page1.html", + .code = "200 Dontcare", + .body = "<html>hello1</html>", + .headers = { + "Content-Type: text/html", + } + }, + { .name = "/page2.html", + .code = "200 Dontcare", + .body = "<html>hello2</html>", + .headers = { + "Content-Type: text/html", + } + } + }; + + // functions won't come back if an error occurs + wget_test_start_server( + WGET_TEST_RESPONSE_URLS, &urls, countof(urls), + 0); + + // test-i + wget_test( +// WGET_TEST_KEEP_TMPFILES, 1, + WGET_TEST_OPTIONS, "-i urls.txt", + WGET_TEST_REQUEST_URL, NULL, + WGET_TEST_EXPECTED_ERROR_CODE, 0, + WGET_TEST_EXISTING_FILES, &(wget_test_file_t []) { + { "urls.txt", urls[0].body }, + { NULL } }, + WGET_TEST_EXPECTED_FILES, &(wget_test_file_t []) { + { urls[0].name + 1, urls[0].body }, + { urls[1].name + 1, urls[1].body }, + { urls[2].name + 1, urls[2].body }, + { NULL } }, + 0); +/* + // test-i-http (expands to -i http://localhost:{{port}}/urls.txt) + wget_test( + WGET_TEST_OPTIONS, "-i", + WGET_TEST_REQUEST_URL, "urls.txt", + WGET_TEST_EXPECTED_ERROR_CODE, 0, + WGET_TEST_EXPECTED_FILES, &(wget_test_file_t []) { + { urls[0].name + 1, urls[0].body }, + { urls[1].name + 1, urls[1].body }, + { urls[2].name + 1, urls[2].body }, + { NULL } }, + 0); +*/ + exit(0); +} diff --git a/tests2/test-i-https.c b/tests2/test-i-https.c new file mode 100644 index 00000000..3f2474ce --- /dev/null +++ b/tests2/test-i-https.c @@ -0,0 +1,155 @@ +/* + * Copyright(c) 2013 Tim Ruehsen + * + * This file is part of libwget. + * + * Libwget is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Libwget is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with libwget. If not, see <http://www.gnu.org/licenses/>. + * + * + * Testing Wget + * + * Changelog + * 08.07.2013 Tim Ruehsen created + * + */ + +#if HAVE_CONFIG_H +# include <config.h> +#endif + +#include <stdlib.h> // exit() +#include "libtest.h" + +int main(void) +{ + wget_test_url_t urls[]={ + { .name = "/urls.txt", + .code = "200 Dontcare", + .body = "https://localhost:{{sslport}}/page1.html\nhttps://localhost:{{sslport}}/page2.html\n", + .headers = { + "Content-Type: text/plain", + } + }, + { .name = "/page1.html", + .code = "200 Dontcare", + .body = "<html>hello1</html>", + .headers = { + "Content-Type: text/html", + } + }, + { .name = "/page2.html", + .code = "200 Dontcare", + .body = "<html>hello2</html>", + .headers = { + "Content-Type: text/html", + } + } + }; + + // functions won't come back if an error occurs + wget_test_start_server( + WGET_TEST_RESPONSE_URLS, &urls, countof(urls), + 0); + + // test-i-https with loading CA Certificate + wget_test( + // WGET_TEST_KEEP_TMPFILES, 1, + WGET_TEST_OPTIONS, "--ca-certificate=../" SRCDIR "/certs/x509-ca-cert.pem --no-ocsp -i urls.txt", + WGET_TEST_REQUEST_URL, NULL, + WGET_TEST_EXPECTED_ERROR_CODE, 0, + WGET_TEST_EXISTING_FILES, &(wget_test_file_t []) { + { "urls.txt", urls[0].body }, + { NULL } }, + WGET_TEST_EXPECTED_FILES, &(wget_test_file_t []) { + { urls[0].name + 1, urls[0].body }, + { urls[1].name + 1, urls[1].body }, + { urls[2].name + 1, urls[2].body }, + { NULL } }, + 0); + + // test-i-https with loading CA Certificate and CRL + wget_test( + // WGET_TEST_KEEP_TMPFILES, 1, + WGET_TEST_OPTIONS, "-d --ca-certificate=../" SRCDIR "/certs/x509-ca-cert.pem --crl-file=../" SRCDIR "/certs/x509-server-crl.pem --no-ocsp -i urls.txt", + WGET_TEST_REQUEST_URL, NULL, + WGET_TEST_EXPECTED_ERROR_CODE, 5, + WGET_TEST_EXISTING_FILES, &(wget_test_file_t []) { + { "urls.txt", urls[0].body }, + { NULL } }, + WGET_TEST_EXPECTED_FILES, &(wget_test_file_t []) { + { urls[0].name + 1, urls[0].body }, + { NULL } }, + 0); + + // test-i-https ignoring unknown certificate + wget_test( + // WGET_TEST_KEEP_TMPFILES, 1, + WGET_TEST_OPTIONS, "--no-check-certificate -i urls.txt", + WGET_TEST_REQUEST_URL, NULL, + WGET_TEST_EXPECTED_ERROR_CODE, 0, + WGET_TEST_EXISTING_FILES, &(wget_test_file_t []) { + { "urls.txt", urls[0].body }, + { NULL } }, + WGET_TEST_EXPECTED_FILES, &(wget_test_file_t []) { + { urls[0].name + 1, urls[0].body }, + { urls[1].name + 1, urls[1].body }, + { urls[2].name + 1, urls[2].body }, + { NULL } }, + 0); + + // test-i-https ignoring unknown certificate (with CRL) + wget_test( + // WGET_TEST_KEEP_TMPFILES, 1, + WGET_TEST_OPTIONS, "--no-check-certificate --crl-file=../" SRCDIR "/certs/x509-server-crl.pem -i urls.txt", + WGET_TEST_REQUEST_URL, NULL, + WGET_TEST_EXPECTED_ERROR_CODE, 0, + WGET_TEST_EXISTING_FILES, &(wget_test_file_t []) { + { "urls.txt", urls[0].body }, + { NULL } }, + WGET_TEST_EXPECTED_FILES, &(wget_test_file_t []) { + { urls[0].name + 1, urls[0].body }, + { urls[1].name + 1, urls[1].body }, + { urls[2].name + 1, urls[2].body }, + { NULL } }, + 0); + + // test-i-https failing due to unknown certificate + wget_test( + // WGET_TEST_KEEP_TMPFILES, 1, + WGET_TEST_OPTIONS, "--tries=1 -i urls.txt", + WGET_TEST_REQUEST_URL, NULL, + WGET_TEST_EXPECTED_ERROR_CODE, 5, + WGET_TEST_EXISTING_FILES, &(wget_test_file_t []) { + { "urls.txt", urls[0].body }, + { NULL } }, + WGET_TEST_EXPECTED_FILES, &(wget_test_file_t []) { + { urls[0].name + 1, urls[0].body }, + { NULL } }, + 0); + +/* + // test-i-http (expands to -i https://localhost:{{sslport}}/urls.txt) + wget_test( + WGET_TEST_OPTIONS, "-i", + WGET_TEST_REQUEST_URL, "urls.txt", + WGET_TEST_EXPECTED_ERROR_CODE, 0, + WGET_TEST_EXPECTED_FILES, &(wget_test_file_t []) { + { urls[0].name + 1, urls[0].body }, + { urls[1].name + 1, urls[1].body }, + { urls[2].name + 1, urls[2].body }, + { NULL } }, + 0); +*/ + exit(0); +} diff --git a/tests2/test-idn-cmd.c b/tests2/test-idn-cmd.c new file mode 100644 index 00000000..4074e7da --- /dev/null +++ b/tests2/test-idn-cmd.c @@ -0,0 +1,89 @@ +/* + * Copyright(c) 2013 Tim Ruehsen + * + * This file is part of libwget. + * + * Libwget is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Libwget is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with libwget. If not, see <http://www.gnu.org/licenses/>. + * + * + * Testing Wget + * + * Changelog + * 17.07.2013 Tim Ruehsen created + * + */ + +#if HAVE_CONFIG_H +# include <config.h> +#endif + +#include <stdlib.h> // exit() +#include "libtest.h" + +// Kon'nichiwa <dot> Japan +#define euc_jp_hostname "\272\243\306\374\244\317.\306\374\313\334" +#define utf8_hostname "\344\273\212\346\227\245\343\201\257.\346\227\245\346\234\254" +#define punycoded_hostname "xn--v9ju72g90p.xn--wgv71a" + +int main(void) +{ + wget_test_url_t urls[]={ + { .name = "http://" punycoded_hostname "/index.html", + .code = "200 Dontcare", + .body = "What ever", + .headers = { + "Content-Type: text/plain", + } + }, + }; + + char options[256]; + + // functions won't come back if an error occurs + wget_test_start_server( + WGET_TEST_RESPONSE_URLS, &urls, countof(urls), + 0); + + // test-idn-cmd + snprintf(options, sizeof(options), + "--iri -rH -e http_proxy=localhost:%d --local-encoding=EUC-JP " euc_jp_hostname, + wget_test_get_http_server_port()); + + wget_test( +// WGET_TEST_KEEP_TMPFILES, 1, + WGET_TEST_OPTIONS, options, + WGET_TEST_REQUEST_URL, NULL, + WGET_TEST_EXPECTED_ERROR_CODE, 0, + WGET_TEST_EXPECTED_FILES, &(wget_test_file_t []) { + { punycoded_hostname "/index.html", urls[0].body }, + { NULL } }, + 0); + + // test-idn-cmd + snprintf(options, sizeof(options), + "--iri -rH -e http_proxy=localhost:%d --local-encoding=UTF-8 " utf8_hostname, + wget_test_get_http_server_port()); + + wget_test( +// WGET_TEST_KEEP_TMPFILES, 1, + WGET_TEST_OPTIONS, options, + WGET_TEST_REQUEST_URL, NULL, + WGET_TEST_EXPECTED_ERROR_CODE, 0, + WGET_TEST_EXPECTED_FILES, &(wget_test_file_t []) { + { punycoded_hostname "/index.html", urls[0].body }, + { NULL } }, + 0); + + exit(0); +} diff --git a/tests2/test-idn-meta.c b/tests2/test-idn-meta.c new file mode 100644 index 00000000..d9010824 --- /dev/null +++ b/tests2/test-idn-meta.c @@ -0,0 +1,101 @@ +/* + * Copyright(c) 2013 Tim Ruehsen + * + * This file is part of libwget. + * + * Libwget is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Libwget is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with libwget. If not, see <http://www.gnu.org/licenses/>. + * + * + * Testing Wget + * + * Changelog + * 17.07.2013 Tim Ruehsen created + * + */ + +#if HAVE_CONFIG_H +# include <config.h> +#endif + +#include <stdlib.h> // exit() +#include "libtest.h" + +// Kon'nichiwa <dot> Japan +#define euc_jp_hostname "\272\243\306\374\244\317.\306\374\313\334" +#define punycoded_hostname "xn--v9ju72g90p.xn--wgv71a" + +// The charset in the document's META tag is stated wrong by purpose (UTF-8). +// The charset in the response header has priority and is correct (EUC-JP) + +int main(void) +{ + wget_test_url_t urls[]={ + { .name = "http://start-here.com/start.html", + .code = "200 Dontcare", + .body = + "<meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\" />" \ + "<a href=\"http://" euc_jp_hostname "/\">The link</a>", + .headers = { + "Content-Type: text/html; charset=EUC-JP", + } + }, + { .name = "http://" punycoded_hostname "/index.html", + .code = "200 Dontcare", + .body = "What ever", + .headers = { + "Content-Type: text/plain", + } + }, + }; + + char options[256]; + + // functions won't come back if an error occurs + wget_test_start_server( + WGET_TEST_RESPONSE_URLS, &urls, countof(urls), + 0); + + // test-idn-meta + snprintf(options, sizeof(options), + "--iri -rH -e http_proxy=localhost:%d http://start-here.com/start.html", + wget_test_get_http_server_port()); + + wget_test( +// WGET_TEST_KEEP_TMPFILES, 1, + WGET_TEST_OPTIONS, options, + WGET_TEST_REQUEST_URL, NULL, + WGET_TEST_EXPECTED_ERROR_CODE, 0, + WGET_TEST_EXPECTED_FILES, &(wget_test_file_t []) { + { "start-here.com/start.html", urls[0].body }, + { punycoded_hostname "/index.html", urls[1].body }, + { NULL } }, + 0); + + // test-idn-headers + urls[0].body = "<a href=\"http://" euc_jp_hostname "/\">The link</a>"; + urls[0].headers[0] = "Content-Type: text/html; charset=EUC-JP"; + + wget_test( +// WGET_TEST_KEEP_TMPFILES, 1, + WGET_TEST_OPTIONS, options, + WGET_TEST_REQUEST_URL, NULL, + WGET_TEST_EXPECTED_ERROR_CODE, 0, + WGET_TEST_EXPECTED_FILES, &(wget_test_file_t []) { + { "start-here.com/start.html", urls[0].body }, + { punycoded_hostname "/index.html", urls[1].body }, + { NULL } }, + 0); + + exit(0); +} diff --git a/tests2/test-idn-robots.c b/tests2/test-idn-robots.c new file mode 100644 index 00000000..9f46680e --- /dev/null +++ b/tests2/test-idn-robots.c @@ -0,0 +1,110 @@ +/* + * Copyright(c) 2013 Tim Ruehsen + * + * This file is part of libwget. + * + * Libwget is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Libwget is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with libwget. If not, see <http://www.gnu.org/licenses/>. + * + * + * Testing Wget + * + * Changelog + * 15.07.2013 Tim Ruehsen created + * + */ + +#if HAVE_CONFIG_H +# include <config.h> +#endif + +#include <stdlib.h> // exit() +#include "libtest.h" + +// Kon'nichiwa <dot> Japan +#define euc_jp_hostname "\272\243\306\374\244\317.\306\374\313\334" +#define utf8_hostname "\344\273\212\346\227\245\343\201\257.\346\227\245\346\234\254" +#define punycoded_hostname "xn--v9ju72g90p.xn--wgv71a" + +int main(void) +{ + wget_test_url_t urls[]={ + { .name = "http://" punycoded_hostname "/index.html", + .code = "200 Dontcare", + .body = "<a href=\"http://" euc_jp_hostname "/foo.txt\">The link</a>", + .headers = { + "Content-Type: text/html; charset=EUC-JP", + } + }, + { .name = "http://" punycoded_hostname "/foo.txt", + .code = "200 Dontcare", + .body = "What ever", + .headers = { + "Content-Type: text/plain", + } + }, + { .name = "http://" punycoded_hostname "/robots.txt", + .code = "200 Dontcare", + .body = "", + .headers = { + "Content-Type: text/plain", + } + }, + }; + + char options[256]; + + // functions won't come back if an error occurs + wget_test_start_server( + WGET_TEST_RESPONSE_URLS, &urls, countof(urls), + 0); + + // test-idn-robots + snprintf(options, sizeof(options), + "--iri -e robots=on -rH -e http_proxy=localhost:%d --local-encoding=EUC-JP http://" euc_jp_hostname "/", + wget_test_get_http_server_port()); + + wget_test( +// WGET_TEST_KEEP_TMPFILES, 1, + WGET_TEST_OPTIONS, options, + WGET_TEST_REQUEST_URL, NULL, + WGET_TEST_EXPECTED_ERROR_CODE, 0, + WGET_TEST_EXPECTED_FILES, &(wget_test_file_t []) { + { punycoded_hostname "/index.html", urls[0].body }, + { punycoded_hostname "/foo.txt", urls[1].body }, + { punycoded_hostname "/robots.txt", urls[2].body }, + { NULL } }, + 0); + + // test-idn-robots-utf8 + snprintf(options, sizeof(options), + "--iri -e robots=on -rH -e http_proxy=localhost:%d --local-encoding=UTF-8 http://" utf8_hostname "/", + wget_test_get_http_server_port()); + + urls[0].body = "<a href=\"http://" utf8_hostname "/foo.txt\">The link</a>", + urls[0].headers[0] = "Content-Type: text/html; charset=UTF-8"; + + wget_test( +// WGET_TEST_KEEP_TMPFILES, 1, + WGET_TEST_OPTIONS, options, + WGET_TEST_REQUEST_URL, NULL, + WGET_TEST_EXPECTED_ERROR_CODE, 0, + WGET_TEST_EXPECTED_FILES, &(wget_test_file_t []) { + { punycoded_hostname "/index.html", urls[0].body }, + { punycoded_hostname "/foo.txt", urls[1].body }, + { punycoded_hostname "/robots.txt", urls[2].body }, + { NULL } }, + 0); + + exit(0); +} diff --git a/tests2/test-iri-disabled.c b/tests2/test-iri-disabled.c new file mode 100644 index 00000000..e00dde06 --- /dev/null +++ b/tests2/test-iri-disabled.c @@ -0,0 +1,147 @@ +/* + * Copyright(c) 2013 Tim Ruehsen + * + * This file is part of libwget. + * + * Libwget is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Libwget is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with libwget. If not, see <http://www.gnu.org/licenses/>. + * + * + * Testing Wget + * + * Changelog + * 17.07.2013 Tim Ruehsen created + * + */ + +#if HAVE_CONFIG_H +# include <config.h> +#endif + +#include <stdlib.h> // exit() +#include "libtest.h" + +#define ccedilla_l15 "\xE7" +#define ccedilla_u8 "\xC3\xA7" +#define eacute_l15 "\xE9" +#define eacute_u8 "\xC3\xA9" +#define eurosign_l15 "\xA4" +#define eurosign_u8 "\xE2\x82\xAC" + +int main(void) +{ + wget_test_url_t urls[]={ + { .name = "/index.html", + .code = "200 Dontcare", + .body = + "<html><head><title>Main Page</title></head><body><p>" \ + "Link to page 1 <a href=\"http://localhost:{{port}}/p1_fran" ccedilla_l15 "ais.html\">La seule page en français</a>." \ + "Link to page 3 <a href=\"http://localhost:{{port}}/p3_" eurosign_l15 eurosign_l15 eurosign_l15 ".html\">My tailor is rich</a>." \ + "</p></body></html>", + .headers = { + "Content-type: text/html; charset=ISO-8859-15", + } + }, + { .name = "/robots.txt", + .code = "200 Dontcare", + .body = "", + .headers = { + "Content-type: text/plain", + } + }, + { .name = "/p1_fran%C3%A7ais.html", // UTF-8 encoded + .code = "200 Dontcare1", + .body = + "<html><head><title>La seule page en fran" ccedilla_l15 "ais</title>" \ + "<meta http-equiv=\"Content-Type\" content=\"text/html; charset=ISO-8859-1\"/></head><body>" \ + "<p>Link to page 2 <a href=\"http://localhost:{{port}}/p2_" eacute_l15 eacute_l15 "n.html\">Die enkele nerderlangstalige pagina</a>." \ + "</p></body></html>", + .headers = { + "Content-type: text/html; charset=UTF-8", + } + }, + { .name = "/p1_fran%E7ais.html", + .code = "200 Dontcare2", + .body = + "<html><head><title>La seule page en fran" ccedilla_l15 "ais</title>" \ + "<meta http-equiv=\"Content-Type\" content=\"text/html; charset=ISO-8859-1\"/></head><body>" \ + "<p>Link to page 2 <a href=\"http://localhost:{{port}}/p2_" eacute_l15 eacute_l15 "n.html\">Die enkele nerderlangstalige pagina</a>." \ + "</p></body></html>", + .headers = { + "Content-type: text/html; charset=UTF-8", + } + }, + { .name = "/p2_%C3%A9%C3%A9n.html", // UTF-8 encoded + .code = "200 Dontcare1", + .body = + "<html><head><title>Die enkele nederlandstalige pagina</title></head>" \ + "<body><p>Één is niet veel maar toch meer dan nul.<br/>" \ + "Nerdelands is een mooie taal... dit zin stuckje spreekt vanzelf, of niet :)<br/>" \ + "</p></body></html>", + .headers = { + "Content-type: text/html; charset=UTF-8", + }, + }, + { .name = "/p2_%E9%E9n.html", + .code = "200 Dontcare2", + .body = + "<html><head><title>Die enkele nederlandstalige pagina</title></head>" \ + "<body><p>Één is niet veel maar toch meer dan nul.<br/>" \ + "Nerdelands is een mooie taal... dit zin stuckje spreekt vanzelf, of niet :)<br/>" \ + "</p></body></html>", + .headers = { + "Content-type: text/html; charset=ISO-8859-1", + }, + }, + { .name = "/p3_%E2%82%AC%E2%82%AC%E2%82%AC.html", // UTF-8 encoded + .code = "200 Dontcare1", + .body = + "<html><head><title>Euro page</title>" \ + "</head><body><p>My tailor isn't rich anymore.</p></body></html>", + .headers = { + "Content-type: text/plain", + }, + }, + { .name = "/p3_%A4%A4%A4.html", + .code = "200 Dontcare2", + .body = + "<html><head><title>Euro page</title>" \ + "</head><body><p>My tailor isn't rich anymore.</p></body></html>", + .headers = { + "Content-type: text/plain", + }, + }, + }; + + // functions won't come back if an error occurs + wget_test_start_server( + WGET_TEST_RESPONSE_URLS, &urls, countof(urls), + 0); + + // test-iri-disabled + wget_test( +// WGET_TEST_KEEP_TMPFILES, 1, + WGET_TEST_OPTIONS, "--no-iri -e robots=on -nH -r", + WGET_TEST_REQUEST_URL, "index.html", + WGET_TEST_EXPECTED_ERROR_CODE, 0, + WGET_TEST_EXPECTED_FILES, &(wget_test_file_t []) { + { urls[0].name + 1, urls[0].body }, // index.html + { urls[1].name + 1, urls[1].body }, // robots.txt + { "p1_fran" ccedilla_u8 "ais.html", urls[3].body }, + { "p2_" eacute_u8 eacute_u8 "n.html", urls[4].body }, + { "p3_" eurosign_u8 eurosign_u8 eurosign_u8 ".html", urls[6].body }, + { NULL } }, + 0); + + exit(0); +} diff --git a/tests2/test-iri-forced-remote.c b/tests2/test-iri-forced-remote.c new file mode 100644 index 00000000..f7c7da9f --- /dev/null +++ b/tests2/test-iri-forced-remote.c @@ -0,0 +1,127 @@ +/* + * Copyright(c) 2013 Tim Ruehsen + * + * This file is part of libwget. + * + * Libwget is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Libwget is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with libwget. If not, see <http://www.gnu.org/licenses/>. + * + * + * Testing Wget + * + * Changelog + * 27.07.2013 Tim Ruehsen created + * + */ + +#if HAVE_CONFIG_H +# include <config.h> +#endif + +#include <stdlib.h> // exit() +#include "libtest.h" + +#define ccedilla_l15 "\xE7" +#define ccedilla_u8 "\xC3\xA7" +#define eurosign_l15 "\xA4" +#define eurosign_u8 "\xE2\x82\xAC" +#define eacute_l15 "\xE9" +#define eacute_u8 "\xC3\xA9" + +int main(void) +{ + wget_test_url_t urls[]={ + { .name = "/index.html", + .code = "200 Dontcare", + .body = + "<html><head><title>Main Page</title></head><body><p>" \ + "Link to page 1 <a href=\"http://localhost:{{port}}/p1_fran" ccedilla_l15 "ais.html\">La seule page en français</a>." \ + "Link to page 1 <a href=\"http://localhost:{{port}}/p3_" eurosign_l15 eurosign_l15 eurosign_l15 ".html\">My tailor is rich</a>." \ + "</p></body></html>", + .headers = { + "Content-type: text/html; charset=ISO-8859-15", + } + }, + { .name = "/robots.txt", + .code = "200 Dontcare", + .body = "", + .headers = { + "Content-type: text/plain", + } + }, + { .name = "/p1_fran%C3%A7ais.html", // UTF-8 encoded + .code = "200 Dontcare", + .body = + "<html><head><title>La seule page en fran" ccedilla_l15 "ais</title>" \ + "<meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\"/></head><body>" \ + "<p>Link to page 2 <a href=\"http://localhost:{{port}}/p2_" eacute_l15 eacute_l15 "n.html\">Die enkele nerderlangstalige pagina</a>." \ + "</p></body></html>", + .headers = { + "Content-type: text/html; charset=ISO-8859-15", // overrides META tag in document + } + }, + { .name = "/p2_%C3%A9%C3%A9n.html", // UTF-8 encoded + .code = "200 Dontcare", + .body = + "<html><head><title>Die enkele nederlandstalige pagina</title>" \ + "</head><body><p>Één is niet veel maar toch meer dan nul.<br/>" \ + "Nerdelands is een mooie taal... dit zin stuckje spreekt vanzelf, of niet :)<br/>" \ + "</p></body></html>", + .headers = { + "Content-type: text/html; charset=UTF-8", + }, + }, + { .name = "/p2_%E9%E9n.html", + .code = "200 Dontcare", + .body = + "<html><head><title>Die enkele nederlandstalige pagina</title>" \ + "</head><body><p>Één is niet veel maar toch meer dan nul.<br/>" \ + "Nerdelands is een mooie taal... dit zin stuckje spreekt vanzelf, of niet :)<br/>" \ + "</p></body></html>", + .headers = { + "Content-type: text/html; charset=ISO-8859-1", + }, + }, + { .name = "/p3_%E2%82%AC%E2%82%AC%E2%82%AC.html", // UTF-8 encoded + .code = "200 Dontcare", + .body = + "<html><head><title>Euro page</title>" \ + "</head><body><p>My tailor isn't rich anymore.</p></body></html>", + .headers = { + "Content-type: text/plain", + }, + }, + }; + + // functions won't come back if an error occurs + wget_test_start_server( + WGET_TEST_RESPONSE_URLS, &urls, countof(urls), + 0); + + // test-iri-disabled + wget_test( + // WGET_TEST_KEEP_TMPFILES, 1, + WGET_TEST_OPTIONS, "-e robots=on --trust-server-names --local-encoding=UTF-8 --remote-encoding=iso-8859-1 -nH -r", + WGET_TEST_REQUEST_URL, "index.html", + WGET_TEST_EXPECTED_ERROR_CODE, 0, + WGET_TEST_EXPECTED_FILES, &(wget_test_file_t []) { + { urls[0].name + 1, urls[0].body }, + { urls[1].name + 1, urls[1].body }, + { "p1_fran" ccedilla_u8 "ais.html", urls[2].body }, + { "p2_" eacute_u8 eacute_u8 "n.html", urls[3].body }, + { "p3_" eurosign_u8 eurosign_u8 eurosign_u8 ".html", urls[5].body }, + { NULL } }, + 0); + + exit(0); +} diff --git a/tests2/test-iri-list.c b/tests2/test-iri-list.c new file mode 100644 index 00000000..192d0be8 --- /dev/null +++ b/tests2/test-iri-list.c @@ -0,0 +1,110 @@ +/* + * Copyright(c) 2013 Tim Ruehsen + * + * This file is part of libwget. + * + * Libwget is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Libwget is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with libwget. If not, see <http://www.gnu.org/licenses/>. + * + * + * Testing Wget + * + * Changelog + * 24.07.2013 Tim Ruehsen created + * + */ + +#if HAVE_CONFIG_H +# include <config.h> +#endif + +#include <stdlib.h> // exit() +#include "libtest.h" + +#define ccedilla_l1 "\xE7" +#define ccedilla_u8 "\xC3\xA7" +#define eacute_l1 "\xE9" +#define eacute_u8 "\xC3\xA9" + +int main(void) +{ + wget_test_url_t urls[]={ + { .name = "/index.html", + .code = "200 Dontcare", + .body = + "<html><head><title>Main Page</title></head><body><p>Mainpage</p></body></html>", + .headers = { + "Content-type: text/html; charset=ISO-8859-15", + } + }, + { .name = "/robots.txt", + .code = "200 Dontcare", + .body = "", + .headers = { + "Content-type: text/plain", + } + }, + { .name = "/p1_fran%C3%A7ais.html", // UTF-8 encoded + .code = "200 Dontcare", + .body = + "<html><head><title>404</title><p>nop</p></body></html>", + .headers = { + "Content-type: text/html; charset=UTF-8", + } + }, + { .name = "/p2_%C3%A9%C3%A9n.html", // UTF-8 encoded + .code = "200 Dontcare1", + .body = + "<html><head><title>Die enkele nederlandstalige pagina</title>" \ + "<meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\"/></head>" \ + "<body><p>Dutch page</p></body></html>", + .headers = { + "Content-type: text/html; charset=ISO-8859-1", + }, + }, + { .name = "/urls.txt", + .code = "200 Dontcare", + .body = + "http://localhost:{{port}}/\r\n" \ + "http://localhost:{{port}}/p1_fran" ccedilla_l1 "ais.html\r\n" \ + "http://localhost:{{port}}/p2_" eacute_l1 eacute_l1 "n.html", + .headers = { + "Content-type: text/plain; charset=ISO-8859-1", + }, + }, + }; + + // functions won't come back if an error occurs + wget_test_start_server( + WGET_TEST_RESPONSE_URLS, &urls, countof(urls), + 0); + + // test-iri-disabled + wget_test( +// WGET_TEST_KEEP_TMPFILES, 1, + WGET_TEST_OPTIONS, "--local-encoding=UTF-8 --input-encoding=ISO-8859-1 --iri --trust-server-names -i urls.txt", + WGET_TEST_REQUEST_URL, NULL, + WGET_TEST_EXPECTED_ERROR_CODE, 0, + WGET_TEST_EXISTING_FILES, &(wget_test_file_t []) { + { "urls.txt", urls[4].body }, + { NULL } }, + WGET_TEST_EXPECTED_FILES, &(wget_test_file_t []) { + { urls[0].name + 1, urls[0].body }, // index.html + { "p1_fran" ccedilla_u8 "ais.html", urls[2].body }, + { "p2_" eacute_u8 eacute_u8 "n.html", urls[3].body }, + { "urls.txt", urls[4].body }, + { NULL } }, + 0); + + exit(0); +} diff --git a/tests2/test-iri-percent.c b/tests2/test-iri-percent.c new file mode 100644 index 00000000..072b2935 --- /dev/null +++ b/tests2/test-iri-percent.c @@ -0,0 +1,92 @@ +/* + * Copyright(c) 2013 Tim Ruehsen + * + * This file is part of libwget. + * + * Libwget is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Libwget is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with libwget. If not, see <http://www.gnu.org/licenses/>. + * + * + * Testing Wget + * + * Changelog + * 23.07.2013 Tim Ruehsen created + * + */ + +#if HAVE_CONFIG_H +# include <config.h> +#endif + +#include <stdlib.h> // exit() +#include "libtest.h" + +// #define ccedilla_l15 "\xE7" +#define ccedilla_l15_pct "%E7" +#define ccedilla_u8 "\xC3\xA7" +#define ccedilla_u8_pct "%C3%A7" +#define eacute_l15 "\xE9" +#define eacute_u8 "\xC3\xA9" +#define eacute_u8_pct "%C3%A9" + +int main(void) +{ + wget_test_url_t urls[]={ + { .name = "/index.html", + .code = "200 Dontcare", + .body = + "<html><head><title>Main Page</title></head><body><p>" \ + "Link to page 1 <a href=\"http://localhost:{{port}}/hello_" ccedilla_l15_pct eacute_l15 ".html\">La seule page en français</a>." \ + "</p></body></html>", + .headers = { + "Content-type: text/html; charset=ISO-8859-15", + } + }, + { .name = "/hello_" ccedilla_u8_pct eacute_u8_pct ".html", + .code = "200 Dontcare", + .body = + "<html><head><title>La seule page en fran" ccedilla_u8 "ais</title>" \ + "<meta http-equiv=\"Content-Type\" content=\"text/html; charset=ISO-8859-15\"/></head><body>" \ + "<p></p></body></html>", + .headers = { + "Content-type: text/html; charset=UTF-8", + } + }, + { .name = "/robots.txt", + .code = "200 Dontcare", + .body = "", + .headers = { + "Content-Type: text/plain", + } + }, + }; + + // functions won't come back if an error occurs + wget_test_start_server( + WGET_TEST_RESPONSE_URLS, &urls, countof(urls), + 0); + + // test-iri-disabled + wget_test( + // WGET_TEST_KEEP_TMPFILES, 1, + WGET_TEST_OPTIONS, "--iri -e robots=off --restrict-file-names=nocontrol -nH -r", + WGET_TEST_REQUEST_URL, "index.html", + WGET_TEST_EXPECTED_ERROR_CODE, 0, + WGET_TEST_EXPECTED_FILES, &(wget_test_file_t []) { + { urls[0].name + 1, urls[0].body }, + { "hello_" ccedilla_u8 eacute_u8 ".html", urls[1].body }, + { NULL } }, + 0); + + exit(0); +} diff --git a/tests2/test-iri.c b/tests2/test-iri.c new file mode 100644 index 00000000..97fd8d3b --- /dev/null +++ b/tests2/test-iri.c @@ -0,0 +1,152 @@ +/* + * Copyright(c) 2013 Tim Ruehsen + * + * This file is part of libwget. + * + * Libwget is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Libwget is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with libwget. If not, see <http://www.gnu.org/licenses/>. + * + * + * Testing Wget + * + * Changelog + * 17.07.2013 Tim Ruehsen created + * + */ + +#if HAVE_CONFIG_H +# include <config.h> +#endif + +#include <stdlib.h> // exit() +#include "libtest.h" + +#define ccedilla_l15 "\xE7" +#define ccedilla_u8 "\xC3\xA7" +#define eacute_l15 "\xE9" +#define eacute_u8 "\xC3\xA9" +#define eurosign_l15 "\xA4" +#define eurosign_u8 "\xE2\x82\xAC" + +int main(void) +{ + wget_test_url_t urls[]={ + { .name = "/index.html", + .code = "200 Dontcare", + .body = + "Link to page 1 <a href=\"http://localhost:{{port}}/p1_fran" ccedilla_l15 "ais.html\">La seule page en français</a>." \ + "Link to page 3 <a href=\"http://localhost:{{port}}/p3_" eurosign_l15 eurosign_l15 eurosign_l15 ".html\">My tailor is rich</a>.", + .headers = { + "Content-type: text/html; charset=ISO-8859-15", + } + }, + { .name = "/robots.txt", + .code = "200 Dontcare", + .body = "", + .headers = { + "Content-type: text/plain", + } + }, + { .name = "/p1_fran%E7ais.html", + .code = "404 Not found", + .body = + "<html><head><title>404</title></head><body><p>What ever</p></body></html>", + .headers = { + "Content-type: text/html; charset=UTF-8", + } + }, + { .name = "/p1_fran%C3%A7ais.html", // UTF-8 encoded + .code = "200 Dontcare", + .body = + "<html><head><title>La seule page en fran" ccedilla_l15 "ais</title>" \ + "<meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\"/></head><body>" \ + "<p>Link to page 2 <a href=\"http://localhost:{{port}}/p2_" eacute_l15 eacute_l15 "n.html\">Die enkele nerderlangstalige pagina</a>." \ + "</p></body></html>", + .headers = { + "Content-type: text/html; charset=ISO-8859-15", // server response overrides META charset attribute + } + }, + { .name = "/p2_%C3%A9%C3%A9n.html", // UTF-8 encoded + .code = "200 Dontcare", + .body = + "<html><head><title>Die enkele nederlandstalige pagina</title>" \ + "<meta http-equiv=\"Content-Type\" content=\"text/html; charset=ISO-8859-15\"/>" \ + "</head><body><p>Één is niet veel maar toch meer dan nul.<br/>" \ + "Nerdelands is een mooie taal... dit zin stuckje spreekt vanzelf, of niet :)<br/>" \ + "<a href=\"http://localhost:{{port}}/p4_m" eacute_u8 eacute_u8 "r.html\">Méér</a>" \ + "</p></body></html>", + .headers = { + "Content-type: text/html; charset=UTF-8", // server response overrides META charset attribute + }, + }, + { .name = "/p3_%E2%82%AC%E2%82%AC%E2%82%AC.html", // UTF-8 encoded + .code = "200 Dontcare", + .body = + "<html><head><title>Euro page</title>" \ + "<meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\"/>" \ + "</head><body><p>My tailor isn't rich anymore.</p></body></html>", + .headers = { + "Content-type: text/plain; charset=ISO-8859-15", + }, + }, + { .name = "/p3_%A4%A4%A4.html", + .code = "200 Dontcare", + .body = + "<html><head><title>Euro page</title>" \ + "<meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\"/>" \ + "</head><body><p>My tailor isn't rich anymore.</p></body></html>", + .headers = { + "Content-type: text/plain; charset=ISO-8859-15", + }, + }, + { .name = "/p4_m%C3%A9%C3%A9r.html", + .code = "200 Dontcare", + .body = + "<html><head><title>Bekende supermarkt</title></head>" \ + "<body><p>Ik ben toch niet gek !</p></body></html>", + .headers = { + "Content-type: text/plain; charset=UTF-8", + }, + }, + }; + + char request_header[256]; + + // functions won't come back if an error occurs + wget_test_start_server( + WGET_TEST_RESPONSE_URLS, &urls, countof(urls), + 0); + + // test-iri + snprintf(request_header, sizeof(request_header), + "Referer: http://localhost:%d/p2_%%C3%%A9%%C3%%A9n.html", + wget_test_get_http_server_port()); + urls[4].request_headers[0] = urls[7].request_headers[0] = request_header; + + wget_test( +// WGET_TEST_KEEP_TMPFILES, 1, + WGET_TEST_OPTIONS, "--iri -e robots=on --trust-server-names --restrict-file-names=nocontrol -nH -r", + WGET_TEST_REQUEST_URL, "index.html", + WGET_TEST_EXPECTED_ERROR_CODE, 0, + WGET_TEST_EXPECTED_FILES, &(wget_test_file_t []) { + { urls[0].name + 1, urls[0].body }, + { urls[1].name + 1, urls[1].body }, + { "p1_fran" ccedilla_u8 "ais.html", urls[3].body }, + { "p2_" eacute_u8 eacute_u8 "n.html", urls[4].body }, + { "p3_" eurosign_u8 eurosign_u8 eurosign_u8 ".html", urls[5].body }, + { "p4_m" eacute_u8 eacute_u8 "r.html", urls[7].body }, + { NULL } }, + 0); + + exit(0); +} diff --git a/tests2/test-k.c b/tests2/test-k.c new file mode 100644 index 00000000..7de5c8a5 --- /dev/null +++ b/tests2/test-k.c @@ -0,0 +1,92 @@ +/* + * Copyright(c) 2013 Tim Ruehsen + * + * This file is part of libwget. + * + * Libwget is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Libwget is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with libwget. If not, see <http://www.gnu.org/licenses/>. + * + * + * Testing Wget + * + * Changelog + * 15.07.2013 Tim Ruehsen created + * + */ + +#if HAVE_CONFIG_H +# include <config.h> +#endif + +#include <stdlib.h> // exit() +#include "libtest.h" + +int main(void) +{ + wget_test_url_t urls[]={ + { .name = "/index.html", + .code = "200 Dontcare", + .body = + "<html><head><title>Main Page</title></head><body><p>A link to a" \ + " <a href=\"second.html\">second page</a>." \ + " <a href=\"htTp://localhost:{{port}}/second.html\">second page</a>." \ + " <a href=\"subdir/third.html\">third page</a>." \ + " <a href=\"htTp://localhost:{{port}}/subdir/third.html\">third page</a>." \ + "</p></body></html>", + .headers = { + "Content-Type: text/html", + } + }, + { .name = "/second.html", + .code = "200 Dontcare", + .body = "<html><head><title>Site</title></head><body>Some Text</body></html>", + .headers = { + "Content-Type: text/html", + } + }, + { .name = "/subdir/third.html", + .code = "200 Dontcare", + .body = "<html><head><title>Site</title></head><body>Some Text</body></html>", + .headers = { + "Content-Type: text/html", + } + }, + }; + + const char *converted = + "<html><head><title>Main Page</title></head><body><p>A link to a" \ + " <a href=\"second.html\">second page</a>." \ + " <a href=\"second.html\">second page</a>." \ + " <a href=\"subdir/third.html\">third page</a>." \ + " <a href=\"subdir/third.html\">third page</a>." \ + "</p></body></html>"; + + // functions won't come back if an error occurs + wget_test_start_server( + WGET_TEST_RESPONSE_URLS, &urls, countof(urls), + 0); + + // test-k + wget_test( + WGET_TEST_OPTIONS, "-k -r -nH", + WGET_TEST_REQUEST_URL, "index.html", + WGET_TEST_EXPECTED_ERROR_CODE, 0, + WGET_TEST_EXPECTED_FILES, &(wget_test_file_t []) { + { urls[0].name + 1, converted }, + { urls[1].name + 1, urls[1].body }, + { urls[2].name + 1, urls[2].body }, + { NULL } }, + 0); + + exit(0); +} diff --git a/tests2/test-meta-robots.c b/tests2/test-meta-robots.c new file mode 100644 index 00000000..60c30a30 --- /dev/null +++ b/tests2/test-meta-robots.c @@ -0,0 +1,101 @@ +/* + * Copyright(c) 2013 Tim Ruehsen + * + * This file is part of libwget. + * + * Libwget is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Libwget is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with libwget. If not, see <http://www.gnu.org/licenses/>. + * + * + * Testing Wget + * + * Changelog + * 15.07.2013 Tim Ruehsen created + * + */ + +#if HAVE_CONFIG_H +# include <config.h> +#endif + +#include <stdlib.h> // exit() +#include "libtest.h" + +int main(void) +{ + wget_test_url_t urls[]={ + { .name = "/start.html", + .code = "200 Dontcare", + .body = + "<meta name= \"roBoTS\" content=\"noFolLow , foo, bar \">" \ + "<a href=\"/bombshell.html\">Don't follow me!</a>", + .headers = { + "Content-Type: text/html", + } + }, + { .name = "/mid.html", + .code = "200 Dontcare", + .body = + "<meta name=\"rObOts\" content=\" foo , NOfOllow , bar \">" \ + "<a href=\"/bombshell.html\">Don't follow me!</a>", + .headers = { + "Content-Type: text/html", + } + }, + { .name = "/end.html", + .code = "200 Dontcare", + .body = + "<meta name=\"RoBotS\" content=\"foo,BAr, nofOLLOw \">" \ + "<a href=\"/bombshell.html\">Don't follow me!</a>", + .headers = { + "Content-Type: text/html", + } + }, + { .name = "/solo.html", + .code = "200 Dontcare", + .body = + "<meta name=\"robots\" content=\"nofollow\">" \ + "<a href=\"/bombshell.html\">Don't follow me!</a>", + .headers = { + "Content-Type: text/html", + } + }, + { .name = "/bombshell.html", + .code = "200 Dontcare", + .body = "What ever", + .headers = { + "Content-Type: text/html", + } + }, + }; + + // functions won't come back if an error occurs + wget_test_start_server( + WGET_TEST_RESPONSE_URLS, &urls, countof(urls), + 0); + + // test-meta-robots + wget_test( + WGET_TEST_OPTIONS, "-r -e robots=on -nd", + WGET_TEST_REQUEST_URLS, "start.html", "mid.html", "end.html", "solo.html", NULL, + WGET_TEST_EXPECTED_ERROR_CODE, 0, + WGET_TEST_EXPECTED_FILES, &(wget_test_file_t []) { + { urls[0].name + 1, urls[0].body }, + { urls[1].name + 1, urls[1].body }, + { urls[2].name + 1, urls[2].body }, + { urls[3].name + 1, urls[3].body }, + { NULL } }, + 0); + + exit(0); +} diff --git a/tests2/test-np.c b/tests2/test-np.c new file mode 100644 index 00000000..ac65270f --- /dev/null +++ b/tests2/test-np.c @@ -0,0 +1,110 @@ +/* + * Copyright(c) 2014 Tim Ruehsen + * + * This file is part of libwget. + * + * Libwget is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Libwget is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with libwget. If not, see <http://www.gnu.org/licenses/>. + * + * + * Testing Wget + * + * Changelog + * 02.07.2014 Tim Ruehsen created + * + */ + +#if HAVE_CONFIG_H +# include <config.h> +#endif + +#include <stdlib.h> // exit() +#include "libtest.h" + +int main(void) +{ + wget_test_url_t urls[]={ + { .name = "/firstlevel/index.html", + .code = "200 Dontcare", + .body = + "<html><head><title>Main Page</title></head><body><p>A link to a" \ + " <A hreF=\"http://localhost:{{port}}/firstlevel/secondpage.html\">second page</a>." \ + " <a href=\"file://path/file_to_be_ignored.txt\">Unsupported file scheme</a>." \ + "</p></body></html>", + .headers = { + "Content-Type: text/html", + } + }, + { .name = "/firstlevel/secondpage.html", + .code = "200 Dontcare", + .body = + "<html><head><title>Second Page</title></head><body><p>A link to a" \ + " <a hRef=\"http://localhost:{{port}}/firstlevel/lowerlevel/thirdpage.html\">third page</a>." \ + "</p></body></html>", + .headers = { + "Content-Type: text/html", + } + }, + { .name = "/firstlevel/lowerlevel/thirdpage.html", + .code = "200 Dontcare", + .body = + "<html><head><title>Third Page</title></head><body><p>A link to a" \ + " <A href=\"http://localhost:{{port}}/higherlevelpage.html\">higher level page</a>." \ + "</p></body></html>", + .headers = { + "Content-Type: text/html", + } + }, + { .name = "/firstlevel/fourthpage.html", + .code = "200 Dontcare", + .body = + "<html><head><title>Fourth Page</title></head><body><p>" \ + "This page is only linked by the higher level page. Therefore, it should not be downloaded." \ + "</p></body></html>", + .headers = { + "Content-Type: text/html", + } + }, + { .name = "/higherlevelpage.html", + .code = "200 Dontcare", + .body = + "<html><head><title>Higher Level Page</title></head><body><p>" \ + "This page is on a higher level in the URL path hierarchy. Therefore, it" \ + "should not be downloaded. Wget should not visit the following link to a" \ + " <a Href=\"http://localhost:{{port}}/firstlevel/fourthpage.html\">fourth page</a>." \ + "</p></body></html>", + .headers = { + "Content-Type: text/html", + } + }, + }; + + // functions won't come back if an error occurs + wget_test_start_server( + WGET_TEST_RESPONSE_URLS, &urls, countof(urls), + 0); + + // test-i + wget_test( + WGET_TEST_OPTIONS, "-np -nH -r", + WGET_TEST_REQUEST_URL, "firstlevel/", + WGET_TEST_EXPECTED_ERROR_CODE, 0, + WGET_TEST_EXPECTED_FILES, &(wget_test_file_t []) { + { urls[0].name + 1, urls[0].body }, + { urls[1].name + 1, urls[1].body }, + { urls[2].name + 1, urls[2].body }, + { NULL } }, + 0); + + exit(0); +} diff --git a/tests2/test-parse-html.c b/tests2/test-parse-html.c new file mode 100644 index 00000000..9241a533 --- /dev/null +++ b/tests2/test-parse-html.c @@ -0,0 +1,210 @@ +/* + * Copyright(c) 2012 Tim Ruehsen + * + * This file is part of MGet. + * + * Wget is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Wget is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Wget. If not, see <http://www.gnu.org/licenses/>. + * + * + * test routines + * + * Changelog + * 16.08.2013 Tim Ruehsen created + * + */ + +#if HAVE_CONFIG_H +#include <config.h> +#endif + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <ctype.h> +#include <dirent.h> +#include <fcntl.h> +#include <sys/stat.h> +#ifdef HAVE_MMAP +#include <sys/mman.h> +#endif + +#include <libwget.h> +#include "../libwget/private.h" +#include "../src2/options.h" + +static int + ok, + failed; + +static const char *test_data[] ={ + "<!doctype html>\n"\ + "<!--[if lt IE 7 ]> <html class=\"no-js ie6\" lang=\"en\"> <![endif]-->\n"\ + "<!--[if (gte IE 9)|!(IE)]><!--> <html class=\"no-js\"> <!--<![endif]-->\n"\ + "<head>\n"\ + " <meta charset=\"utf-8\">\n"\ + " <script>window.jQuery || document.write(\"<script src='/common/inc/js/jquery-1.5.1.min.js'><\\/script>\")</script>\n"\ + " <script src=\"/common/inc/js/core.js?v=1\"></script>\n"\ + "</head>\n"\ + "<body>\n"\ + " <ul>\n"\ + " <li><a href=\"/solutions/platform.html#server\">Server</a></li>\n"\ + " <li><a href=\"/solutions/platform.html#desktop\">Desktop</a></li>\n"\ + " </ul>\n"\ + "</body>\n"\ + "</html>\n" +}; + +static void html_dump(void *user_ctx, int flags, const char *dir G_GNUC_WGET_UNUSED, const char *attr, const char *val, size_t len, size_t pos) +{ +// info_printf("\n%02X %s %s '%.*s' %zd %zd\n", flags, dir, attr, (int) len, val, len, pos); + if ((flags & XML_FLG_ATTRIBUTE) && val) { + int found = 0; + + // info_printf("%02X %s %s '%.*s' %zd %zd\n", flags, dir, attr, (int) len, val, len, pos); + + // very simplified + // see http://stackoverflow.com/questions/2725156/complete-list-of-html-tag-attributes-which-have-a-url-value + switch (tolower(*attr)) { + case 'h': + found = !wget_strcasecmp_ascii(attr, "href"); + break; + case 's': + found = !wget_strcasecmp_ascii(attr, "src"); + break; + } + + if (found) { + // check if len and pos matches + const char *doc = (const char *)user_ctx; + + if (memcmp(doc + pos, val, len)) { + failed++; + error_printf_exit("Not found: '%.*s' expected at pos %zd with length %zd\n", (int) len, val, pos, len); + } else + ok++; + } + } + return; +/* + if (flags & XML_FLG_BEGIN) { + const char *p = *dir == '/' ? strrchr(dir, '/') : dir; + if (p) { + if (*dir == '/') p++; + if (flags == (XML_FLG_BEGIN | XML_FLG_END)) { + info_printf("<%s/>", p); + return; + } + info_printf("<%s", p); + } + } + if (flags & XML_FLG_ATTRIBUTE) { + if (val) + info_printf(" %s=\"%.*s\"", attr, (int) len, val); + else + info_printf(" %s", attr); // HTML bareword attribute + } + if (flags & XML_FLG_CLOSE) { + info_printf(">"); + } + if (flags & XML_FLG_CONTENT) { + info_printf("%.*s", (int) len, val); + } + if (flags & XML_FLG_END) { + const char *p = *dir == '/' ? strrchr(dir, '/') : dir; + if (p) { + if (*dir == '/') p++; + info_printf("</%s>", p); + } + } + + if (flags == XML_FLG_COMMENT) + info_printf("<!--%.*s-->", (int) len, val); + else if (flags == XML_FLG_PROCESSING) + info_printf("<?%.*s?>", (int) len, val); + else if (flags == XML_FLG_SPECIAL) + info_printf("<!%.*s>", (int) len, val); +*/ +} + +static void test_parse_buffer(void) +{ + unsigned it; + + for (it = 0; it < countof(test_data); it++) { + wget_html_parse_buffer(test_data[it], html_dump, (void *)test_data[it], 0); + } +} + +static void test_parse_files(void) +{ + DIR *dirp; + struct dirent *dp; + const char *ext; + char fname[128]; + int xml = 0, html = 0, css = 0, type; + + // test the XML / HTML parser, you should start the test with valgrind + // to detect memory faults + if ((dirp = opendir(SRCDIR "/files")) != NULL) { + while ((dp = readdir(dirp)) != NULL) { + if (*dp->d_name == '.') continue; + if ((ext = strrchr(dp->d_name, '.'))) { + if (!wget_strcasecmp_ascii(ext, ".xml")) + type = 1; + else if (!wget_strcasecmp_ascii(ext, ".html")) + type = 2; + else + continue; + + snprintf(fname, sizeof(fname), SRCDIR "/files/%s", dp->d_name); + info_printf("parsing %s\n", fname); + + char *data; + + if ((data = wget_read_file(fname, NULL))) { + if (type == 1) { + wget_xml_parse_buffer(data, html_dump, data, 0); + xml++; + } else { + wget_html_parse_buffer(data, html_dump, data, 0); + html++; + } + + xfree(data); + } + } + } + closedir(dirp); + } + + info_printf("%d XML, %d HTML and %d CSS files parsed\n", xml, html, css); +} + +int main(int argc, const char * const *argv) +{ + init(argc, argv); // allows us to test with options (e.g. with --debug) + + test_parse_buffer(); + test_parse_files(); + + deinit(); // free resources allocated by init() + + if (failed) { + info_printf("Summary: %d out of %d tests failed\n", failed, ok + failed); + return 1; + } + + info_printf("Summary: All %d tests passed\n", ok + failed); + return 0; +} diff --git a/tests2/test-parse-rss.c b/tests2/test-parse-rss.c new file mode 100644 index 00000000..0c0a7ef6 --- /dev/null +++ b/tests2/test-parse-rss.c @@ -0,0 +1,99 @@ +/* + * Copyright(c) 2013 Tim Ruehsen + * + * This file is part of libwget. + * + * Libwget is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Libwget is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with libwget. If not, see <http://www.gnu.org/licenses/>. + * + * + * Testing Wget + * + * Changelog + * 25.12.2013 Tim Ruehsen created + * + */ + +#if HAVE_CONFIG_H +# include <config.h> +#endif + +#include <stdlib.h> // exit() +#include <string.h> // strlen() +#include "libtest.h" + +int main(void) +{ + wget_test_url_t urls[]={ + { .name = "/main.rss", + .body = +"<?xml version=\"1.0\" encoding=\"utf-8\"?>"\ +"<channel>"\ +"<title>Da title</title>"\ +"<link>http://localhost:{{port}}/page1.html</link>"\ +"<description>Nice article</description>"\ +"<item>"\ +"<title>Item title</title>"\ +"<link>http://localhost:{{port}}/page2.html</link>"\ +"<pubDate>Sun, 01 Sep 2013 18:41:05 -0700</pubDate>"\ +"<guid isPermaLink=\"true\">http://localhost:{{port}}/page3.html</guid>"\ +"<description>item description</description>"\ +"</item></channel></rss>", + }, + { .name = "/page1.html", + .code = "200 Dontcare", + .body = "<html>hello1</html>", + .headers = { + "Content-Type: text/html", + } + }, + { .name = "/page2.html", + .code = "200 Dontcare", + .body = "<html>hello2</html>", + .headers = { + "Content-Type: text/html", + } + }, + { .name = "/page3.html", + .code = "200 Dontcare", + .body = "<html>hello3</html>", + .headers = { + "Content-Type: text/html", + } + } + }; + + // functions won't come back if an error occurs + wget_test_start_server( + WGET_TEST_RESPONSE_URLS, &urls, countof(urls), + 0); + + // test--parse-rss + wget_test( + // WGET_TEST_KEEP_TMPFILES, 1, + WGET_TEST_OPTIONS, "--force-rss -i main.rss", + WGET_TEST_REQUEST_URL, NULL, + WGET_TEST_EXPECTED_ERROR_CODE, 0, + WGET_TEST_EXISTING_FILES, &(wget_test_file_t []) { + { "main.rss", urls[0].body }, + { NULL } }, + WGET_TEST_EXPECTED_FILES, &(wget_test_file_t []) { + { urls[0].name + 1, urls[0].body }, + { urls[1].name + 1, urls[1].body }, + { urls[2].name + 1, urls[2].body }, + { urls[3].name + 1, urls[3].body }, + { NULL } }, + 0); + + exit(0); +} diff --git a/tests2/test-restrict-ascii.c b/tests2/test-restrict-ascii.c new file mode 100644 index 00000000..3939d5b5 --- /dev/null +++ b/tests2/test-restrict-ascii.c @@ -0,0 +1,89 @@ +/* + * Copyright(c) 2013 Tim Ruehsen + * + * This file is part of libwget. + * + * Libwget is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Libwget is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with libwget. If not, see <http://www.gnu.org/licenses/>. + * + * + * Testing Wget + * + * Changelog + * 08.07.2013 Tim Ruehsen created + * + */ + +#if HAVE_CONFIG_H +# include <config.h> +#endif + +#include <stdlib.h> // exit() +#include <string.h> // strlen() +#include "libtest.h" + +static const char *mainpage = "\ +<html>\n\ +<head>\n\ + <title>Main Page</title>\n\ +</head>\n\ +<body>\n\ + <p>\n\ + Don't care.\n\ + </p>\n\ +</body>\n\ +</html>\n"; + +int main(void) +{ + wget_test_url_t urls[]={ +// { .name = "/%CE%B3%CE%BD%CF%89%CF%83%CE%B9%CF%82.html", // "gnosis" in UTF-8 greek + { .name = "/%CE%B3%CE%BD%E1%BF%B6%CF%83%CE%B9%CF%82.html", // "gnosis" in UTF-8 greek + .code = "200 Dontcare", + .body = mainpage, + .headers = { + "Content-Type: text/html", + } + } + }; + + // functions won't come back if an error occurs + wget_test_start_server( + WGET_TEST_RESPONSE_URLS, &urls, countof(urls), + 0); + + // test-restrict-ascii + wget_test( +// WGET_TEST_KEEP_TMPFILES, 1, + WGET_TEST_OPTIONS, "--restrict-file-names=ascii", + WGET_TEST_REQUEST_URL, urls[0].name + 1, + WGET_TEST_EXPECTED_ERROR_CODE, 0, + WGET_TEST_EXPECTED_FILES, &(wget_test_file_t []) { + { urls[0].name + 1, urls[0].body }, + { NULL } }, + 0); + + // test-restrict-ascii +/* + wget_test( + WGET_TEST_KEEP_TMPFILES, 1, + WGET_TEST_OPTIONS, "--local-encoding=utf-8", + WGET_TEST_REQUEST_URL, urls[0].name + 1, + WGET_TEST_EXPECTED_ERROR_CODE, 0, + WGET_TEST_EXPECTED_FILES, &(wget_test_file_t []) { + { urls[0].name + 1, urls[0].body }, + { NULL } }, + 0); +*/ + exit(0); +} diff --git a/tests2/test-wget-1.c b/tests2/test-wget-1.c new file mode 100644 index 00000000..ee1c3b27 --- /dev/null +++ b/tests2/test-wget-1.c @@ -0,0 +1,553 @@ +/* + * Copyright(c) 2013 Tim Ruehsen + * + * This file is part of libwget. + * + * Libwget is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Libwget is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with libwget. If not, see <http://www.gnu.org/licenses/>. + * + * + * Testing Wget + * + * Changelog + * 10.03.2013 Tim Ruehsen created + * + */ + +#if HAVE_CONFIG_H +# include <config.h> +#endif + +#include <stdlib.h> // exit() +#include <string.h> // strlen() +#include "libtest.h" + +static const char *mainpage = "\ +<html>\n\ +<head>\n\ + <title>Main Page</title>\n\ +</head>\n\ +<body>\n\ + <p>\n\ + Some text and a link to a <a href=\"http://localhost:{{port}}/secondpage.html\">second page</a>.\n\ + Also, a <a href=\"http://localhost:{{port}}/nonexistent\">broken link</a>.\n\ + </p>\n\ +</body>\n\ +</html>\n"; + +static const char *secondpage = "\ +<html>\n\ +<head>\n\ + <title>Main Page</title>\n\ +</head>\n\ +<body>\n\ + <p>\n\ + Some text and a link to a <a href=\"http://localhost:{{port}}/thirdpage.html\">third page</a>.\n\ + Also, a <a href=\"http://localhost:{{port}}/nonexistent\">broken link</a>.\n\ + </p>\n\ +</body>\n\ +</html>\n"; + +static const char *thirdpage = "\ +<html>\n\ +<head>\n\ + <title>Main Page</title>\n\ +</head>\n\ +<body>\n\ + <p>\n\ + Some text and a link to a <a href=\"http://localhost:{{port}}/dummy.txt\">dummy text</a>.\n\ + Also, a <a href=\"http://localhost:{{port}}/againnonexistent\">broken link</a>.\n\ + </p>\n\ +</body>\n\ +</html>\n"; + +static const char *dummypage = "\ +<html>\n\ +<head>\n\ + <title>Main Page</title>\n\ +</head>\n\ +<body>\n\ + <p>\n\ + Don't care.\n\ + </p>\n\ +</body>\n\ +</html>\n"; + +int main(void) +{ + wget_test_url_t urls[]={ + { .name = "/index.html", + .code = "200 Dontcare", + .body = mainpage, + .headers = { + "Content-Type: text/html", + } + }, + { .name = "/secondpage.html", + .code = "200 Dontcare", + .body = secondpage, + .headers = { + "Content-Type: text/html", + } + }, + { .name = "/thirdpage.html", + .code = "200 Dontcare", + .body = thirdpage, + .headers = { + "Content-Type: text/html", + } + }, + { .name = "/dummy.txt", + .code = "200 Dontcare", + .body = "Don't care.", + .headers = { + "Content-Type: text/plain", + }, + }, + { .name = "/dummy.html", + .code = "200 Dontcare", + .body = dummypage, + .headers = { + "Content-Type: text/plain", + "Content-Disposition: attachment; filename=\"filename.html\"", + } + }, + { .name = "/dummy2.html", + .code = "200 Dontcare", + .body = dummypage, + .headers = { + "Content-Type: text/plain", + "Content-Disposition: attachment; filename*=UTF-8''%66ile_fran%c3%A7ais.html", + } + } + }; + + // functions won't come back if an error occurs + wget_test_start_server( + WGET_TEST_RESPONSE_URLS, &urls, countof(urls), + 0); + + // test-noop + wget_test( + WGET_TEST_REQUEST_URL, "index.html", + WGET_TEST_EXPECTED_ERROR_CODE, 0, + WGET_TEST_EXPECTED_FILES, &(wget_test_file_t []) { + { "index.html", urls[0].body }, + { NULL } }, + 0); + + // test-nonexistent-quiet + wget_test( + WGET_TEST_OPTIONS, "--quiet", + WGET_TEST_REQUEST_URL, "nonexistent", + WGET_TEST_EXPECTED_ERROR_CODE, 8, + 0); + + // test-stdouterr + wget_test( + WGET_TEST_OPTIONS, "-c -O /dev/full", + WGET_TEST_REQUEST_URL, "dummy.txt", + WGET_TEST_EXPECTED_ERROR_CODE, 3, + 0); + + // test--spider + wget_test( + WGET_TEST_OPTIONS, "--spider", + WGET_TEST_REQUEST_URL, "index.html", + WGET_TEST_EXPECTED_ERROR_CODE, 0, + 0); + + // test--spider-fail + wget_test( + WGET_TEST_OPTIONS, "--spider", + WGET_TEST_REQUEST_URL, "nonexistent", + WGET_TEST_EXPECTED_ERROR_CODE, 8, + 0); + + // test--spider-r--no-content-disposition-trivial + wget_test( + WGET_TEST_OPTIONS, "--spider -r --no-content-disposition", + WGET_TEST_REQUEST_URL, "", + WGET_TEST_EXPECTED_ERROR_CODE, 8, + 0); + + // test--no-content-disposition-trivial + wget_test( + WGET_TEST_OPTIONS, "--no-content-disposition", + WGET_TEST_REQUEST_URL, "index.html", + WGET_TEST_EXPECTED_ERROR_CODE, 0, + WGET_TEST_EXPECTED_FILES, &(wget_test_file_t []) { + { "index.html", urls[0].body }, + { NULL } }, + 0); + + urls[1].headers[1] = "Content-Disposition: attachment; filename=\"filename.html\""; + + // test--no-content-disposition + wget_test( + WGET_TEST_OPTIONS, "--no-content-disposition", + WGET_TEST_REQUEST_URL, "index.html", + WGET_TEST_EXPECTED_ERROR_CODE, 0, + WGET_TEST_EXPECTED_FILES, &(wget_test_file_t []) { + { "index.html", urls[0].body }, + { NULL } }, + 0); + + // test--spider-r--no-content-disposition + wget_test( + WGET_TEST_OPTIONS, "--spider -r --no-content-disposition", + WGET_TEST_REQUEST_URL, "", + WGET_TEST_EXPECTED_ERROR_CODE, 8, + 0); + + urls[1].headers[1] = NULL; + + // test--HTTP-content-disposition + wget_test( + WGET_TEST_OPTIONS, "-e contentdisposition=on", + WGET_TEST_REQUEST_URL, "dummy.html", + WGET_TEST_EXPECTED_ERROR_CODE, 0, + WGET_TEST_EXPECTED_FILES, &(wget_test_file_t []) { + { "filename.html", dummypage }, + { NULL } }, + 0); + + // test--HTTP-content-disposition-1 + wget_test( + WGET_TEST_OPTIONS, "-e contentdisposition=on", + WGET_TEST_REQUEST_URL, "dummy.html", + WGET_TEST_EXPECTED_ERROR_CODE, 0, + WGET_TEST_EXISTING_FILES, &(wget_test_file_t []) { + { "filename.html", "dontcare" }, + { "filename.html.1", "dontcare" }, + { NULL } }, + WGET_TEST_EXPECTED_FILES, &(wget_test_file_t []) { + { "filename.html", "dontcare" }, + { "filename.html.1", "dontcare" }, + { "filename.html.2", dummypage }, + { NULL } }, + 0); + + // test--HTTP-content-disposition-2 + wget_test( + WGET_TEST_OPTIONS, "--no-content-disposition", + WGET_TEST_REQUEST_URL, "dummy.html", + WGET_TEST_EXPECTED_ERROR_CODE, 0, + WGET_TEST_EXISTING_FILES, &(wget_test_file_t []) { + { "filename.html", "dontcare" }, + { "filename.html.1", "dontcare" }, + { NULL } }, + WGET_TEST_EXPECTED_FILES, &(wget_test_file_t []) { + { "filename.html", "dontcare" }, + { "filename.html.1", "dontcare" }, + { "dummy.html", dummypage }, + { NULL } }, + 0); + + // test--HTTP-content-disposition-RFC6266 +#define ccedilla_u8 "\xC3\xA7" + wget_test( + WGET_TEST_OPTIONS, "-e contentdisposition=on --local-encoding=utf-8", + WGET_TEST_REQUEST_URL, "dummy2.html", + WGET_TEST_EXPECTED_ERROR_CODE, 0, + WGET_TEST_EXISTING_FILES, &(wget_test_file_t []) { + { "filename.html", "dontcare" }, + { "filename.html.1", "dontcare" }, + { NULL } }, + WGET_TEST_EXPECTED_FILES, &(wget_test_file_t []) { + { "filename.html", "dontcare" }, + { "filename.html.1", "dontcare" }, + { "file_fran" ccedilla_u8 "ais.html", dummypage }, + { NULL } }, + 0); + + urls[3].headers[1] = "Last-Modified: Sat, 09 Oct 2004 08:30:00 GMT"; + + // test-N--no-content-disposition-trivial + wget_test( + WGET_TEST_OPTIONS, "-N --no-content-disposition", + WGET_TEST_REQUEST_URL, "dummy.txt", + WGET_TEST_EXPECTED_ERROR_CODE, 0, + WGET_TEST_EXPECTED_FILES, &(wget_test_file_t []) { + { "dummy.txt", urls[3].body, 1097310600 }, + { NULL } }, + 0); + + urls[3].headers[2] = "Content-Disposition: attachment; filename=\"filename.txt\""; + + // test-N--no-content-disposition + wget_test( + WGET_TEST_OPTIONS, "-N --no-content-disposition", + WGET_TEST_REQUEST_URL, "dummy.txt", + WGET_TEST_EXPECTED_ERROR_CODE, 0, + WGET_TEST_EXPECTED_FILES, &(wget_test_file_t []) { + { "dummy.txt", urls[3].body, 1097310600 }, + { NULL } }, + 0); + + // test-N-HTTP--content-disposition + wget_test( + WGET_TEST_OPTIONS, "-N --content-disposition", + WGET_TEST_REQUEST_URL, "dummy.txt", + WGET_TEST_EXPECTED_ERROR_CODE, 0, + WGET_TEST_EXPECTED_FILES, &(wget_test_file_t []) { + { "filename.txt", urls[3].body, 1097310600 }, + { NULL } }, + 0); + + urls[3].headers[2] = NULL; + + { + // server sends same length content with slightly different content + char modified[strlen(urls[3].body) + 1]; + + strcpy(modified,urls[3].body); + modified[3] = 'x'; + + urls[3].modified = 1097310600; + + // test-N-current + wget_test( + WGET_TEST_OPTIONS, "-N", + WGET_TEST_REQUEST_URL, "dummy.txt", + WGET_TEST_EXPECTED_ERROR_CODE, 0, + WGET_TEST_EXISTING_FILES, &(wget_test_file_t []) { + { "dummy.txt", modified, 1097310600 }, + { NULL } }, + WGET_TEST_EXPECTED_FILES, &(wget_test_file_t []) { + { "dummy.txt", modified, 1097310600 }, + { NULL } }, + 0); + + // test-N-old + wget_test( + WGET_TEST_OPTIONS, "-N", + WGET_TEST_REQUEST_URL, "dummy.txt", + WGET_TEST_EXPECTED_ERROR_CODE, 0, + WGET_TEST_EXISTING_FILES, &(wget_test_file_t []) { + { "dummy.txt", modified, 1097310000 }, // earlier timestamp + { NULL } }, + WGET_TEST_EXPECTED_FILES, &(wget_test_file_t []) { + { "dummy.txt", urls[3].body, 1097310600 }, + { NULL } }, + 0); + +/* + // test-N-smaller + // This test just works with a HEAD request. But Wget uses If-Modified-Since. + const char *old_body = urls[3].body; + modified[strlen(modified)-2] = 0; + urls[3].body = modified; + wget_test( + WGET_TEST_OPTIONS, "-N", + WGET_TEST_REQUEST_URL, "dummy.txt", + WGET_TEST_EXPECTED_ERROR_CODE, 0, + WGET_TEST_EXISTING_FILES, &(wget_test_file_t []) { + { "dummy.txt", old_body, 1097310600 }, + { NULL } }, + WGET_TEST_EXPECTED_FILES, &(wget_test_file_t []) { + { "dummy.txt", modified, 1097310600 }, + { NULL } }, + 0); + urls[3].body = old_body; // restore body +*/ + } + + // test-N + wget_test( + WGET_TEST_OPTIONS, "-N", + WGET_TEST_REQUEST_URL, "dummy.txt", + WGET_TEST_EXPECTED_ERROR_CODE, 0, + WGET_TEST_EXPECTED_FILES, &(wget_test_file_t []) { + { "dummy.txt", urls[3].body, 0}, + { NULL } }, + 0); + + urls[3].headers[1] = NULL; + +/* + // test-N-no-info + // This test just works with a HEAD request. But Wget uses If-Modified-Since. + wget_test( + WGET_TEST_OPTIONS, "-N", + WGET_TEST_REQUEST_URL, "dummy.txt", + WGET_TEST_EXPECTED_ERROR_CODE, 0, + WGET_TEST_EXISTING_FILES, &(wget_test_file_t []) { + { "dummy.txt", "anycontent", 1097310600 }, + { NULL } }, + WGET_TEST_EXPECTED_FILES, &(wget_test_file_t []) { + { "dummy.txt", urls[3].body, 0}, + { NULL } }, + 0); +*/ + + urls[1].headers[1] = "Content-Disposition: attachment; filename=\"filename.html\""; + + // test-O--no-content-disposition + wget_test( + WGET_TEST_OPTIONS, "-O out --no-content-disposition", + WGET_TEST_REQUEST_URL, "dummy.txt", + WGET_TEST_EXPECTED_ERROR_CODE, 0, + WGET_TEST_EXPECTED_FILES, &(wget_test_file_t []) { + { "out", urls[3].body }, + { NULL } }, + 0); + + // test-O-HTTP-content-disposition + wget_test( + WGET_TEST_OPTIONS, "-O out", + WGET_TEST_REQUEST_URL, "dummy.txt", + WGET_TEST_EXPECTED_ERROR_CODE, 0, + WGET_TEST_EXPECTED_FILES, &(wget_test_file_t []) { + { "out", urls[3].body }, + { NULL } }, + 0); + + + urls[3].headers[1] = NULL; + + // test-O-nc + wget_test( + WGET_TEST_OPTIONS, "-nc -O out", + WGET_TEST_REQUEST_URL, "dummy.txt", + WGET_TEST_EXPECTED_ERROR_CODE, 0, + WGET_TEST_EXPECTED_FILES, &(wget_test_file_t []) { + { "out", urls[3].body }, + { NULL } }, + 0); + + // test-O-nonexisting + wget_test( + WGET_TEST_OPTIONS, "-O out", + WGET_TEST_REQUEST_URL, "nonexistent", + WGET_TEST_EXPECTED_ERROR_CODE, 8, + WGET_TEST_EXPECTED_FILES, &(wget_test_file_t []) { + // { "out", "" }, // Wget would create an empty file here, but Wget not + { NULL } }, + 0); + + // test-O + wget_test( + WGET_TEST_OPTIONS, "-O out", + WGET_TEST_REQUEST_URL, "dummy.txt", + WGET_TEST_EXPECTED_ERROR_CODE, 0, + WGET_TEST_EXPECTED_FILES, &(wget_test_file_t []) { + { "out", urls[3].body }, + { NULL } }, + 0); + + // test-restrict-lowercase + urls[3].name="/DuMmy.Txt"; + wget_test( + WGET_TEST_OPTIONS, "--restrict-file-names=lowercase", + WGET_TEST_REQUEST_URL, "DuMmy.Txt", + WGET_TEST_EXPECTED_ERROR_CODE, 0, + WGET_TEST_EXPECTED_FILES, &(wget_test_file_t []) { + { "dummy.txt", urls[3].body }, + { NULL } }, + 0); + + // test-restrict-uppercase + wget_test( + WGET_TEST_OPTIONS, "--restrict-file-names=uppercase", + WGET_TEST_REQUEST_URL, "DuMmy.Txt", + WGET_TEST_EXPECTED_ERROR_CODE, 0, + WGET_TEST_EXPECTED_FILES, &(wget_test_file_t []) { + { "DUMMY.TXT", urls[3].body }, + { NULL } }, + 0); + urls[3].name="/dummy.txt"; + + // test-c-full + wget_test( + WGET_TEST_OPTIONS, "-c", + WGET_TEST_REQUEST_URL, "dummy.txt", + WGET_TEST_EXPECTED_ERROR_CODE, 0, + WGET_TEST_EXISTING_FILES, &(wget_test_file_t []) { + { "dummy.txt", urls[3].body }, + { NULL } }, + WGET_TEST_EXPECTED_FILES, &(wget_test_file_t []) { + { "dummy.txt", urls[3].body }, + { NULL } }, + 0); + + { + // server sends same length content with slightly different content + char *partial = strndup(urls[3].body, strlen(urls[3].body)-2); + + // test-c-partial + wget_test( + WGET_TEST_OPTIONS, "-c", + WGET_TEST_REQUEST_URL, "dummy.txt", +// WGET_TEST_KEEP_TMPFILES, 1, + WGET_TEST_EXPECTED_ERROR_CODE, 0, + WGET_TEST_EXISTING_FILES, &(wget_test_file_t []) { + { "dummy.txt", partial }, + { NULL } }, + WGET_TEST_EXPECTED_FILES, &(wget_test_file_t []) { + { "dummy.txt", urls[3].body }, + { NULL } }, + 0); + + wget_xfree(partial); + } + +/* + * this test needs a broken server ... I don't have one right now. + { + // server sends same length content with slightly different content + char *partial = strndup(urls[3].body, strlen(urls[3].body)-2); + const char *old_body = urls[3].body; + urls[3].body = ""; + + // test-c-shorter + wget_test( + WGET_TEST_OPTIONS, "-d -c", + WGET_TEST_REQUEST_URL, "dummy.txt", +// WGET_TEST_KEEP_TMPFILES, 1, + WGET_TEST_EXPECTED_ERROR_CODE, 0, + WGET_TEST_EXISTING_FILES, &(wget_test_file_t []) { + { "dummy.txt", partial }, + { NULL } }, + WGET_TEST_EXPECTED_FILES, &(wget_test_file_t []) { + { "dummy.txt", urls[3].body }, + { NULL } }, + 0); + + urls[3].body = old_body; + wget_xfree(partial); + } +*/ + // test-c + wget_test( + WGET_TEST_OPTIONS, "-c", + WGET_TEST_REQUEST_URL, "dummy.txt", + WGET_TEST_EXPECTED_ERROR_CODE, 0, + // no existing file + WGET_TEST_EXPECTED_FILES, &(wget_test_file_t []) { + { "dummy.txt", urls[3].body }, + { NULL } }, + 0); + + // test--https-only + wget_test( + WGET_TEST_OPTIONS, "--https-only -r -nH", + WGET_TEST_REQUEST_URL, "index.html", + WGET_TEST_EXPECTED_ERROR_CODE, 0, + WGET_TEST_EXPECTED_FILES, &(wget_test_file_t []) { + { "index.html", urls[0].body }, + { NULL } }, + 0); + + exit(0); +} diff --git a/tests2/test.c b/tests2/test.c new file mode 100644 index 00000000..57f6c91b --- /dev/null +++ b/tests2/test.c @@ -0,0 +1,1499 @@ +/* + * Copyright(c) 2012 Tim Ruehsen + * + * This file is part of MGet. + * + * Wget is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Wget is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Wget. If not, see <http://www.gnu.org/licenses/>. + * + * + * test routines + * + * Changelog + * 06.07.2012 Tim Ruehsen created + * + */ + +#if HAVE_CONFIG_H +# include <config.h> +#endif + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <dirent.h> +#include <time.h> + +#include <libwget.h> +#include "../libwget/private.h" + +#include "../src2/options.h" +#include "../src2/log.h" + +static int + ok, + failed; + +static void _test_buffer(wget_buffer_t *buf, const char *name) +{ + char test[256]; + int it; + + for (it = 0; it < (int)sizeof(test)-1; it++) { + test[it] = 'a' + it % 26; + test[it + 1] = 0; + + wget_buffer_strcpy(buf, test); + wget_buffer_strcat(buf, test); + + if (!strncmp(buf->data, test, it + 1) && !strncmp(buf->data + it + 1, test, it + 1)) { + ok++; + } else { + failed++; + info_printf("test_buffer.1 '%s': [%d] got %s (expected %s%s)\n", name, it, buf->data, test, test); + } + + wget_buffer_memcpy(buf, test, it + 1); + wget_buffer_memcat(buf, test, it + 1); + + if (!strncmp(buf->data, test, it + 1) && !strncmp(buf->data + it + 1, test, it + 1)) { + ok++; + } else { + failed++; + info_printf("test_buffer.2 '%s': [%d] got %s (expected %s%s)\n", name, it, buf->data, test, test); + } + + wget_buffer_printf(buf, "%s%s", test, test); + + if (!strncmp(buf->data, test, it + 1) && !strncmp(buf->data + it + 1, test, it + 1)) { + ok++; + } else { + failed++; + info_printf("test_buffer.3 '%s': [%d] got %s (expected %s%s)\n", name, it, buf->data, test, test); + } + + wget_buffer_printf(buf, "%s", test); + wget_buffer_printf_append(buf, "%s", test); + + if (!strncmp(buf->data, test, it + 1) && !strncmp(buf->data + it + 1, test, it + 1)) { + ok++; + } else { + failed++; + info_printf("test_buffer.4 '%s': [%d] got %s (expected %s%s)\n", name, it, buf->data, test, test); + } + } +} + +static void test_buffer(void) +{ + char sbuf[16]; + wget_buffer_t buf, *bufp; + + // testing buffer on stack, using initial stack memory + // without resizing + + wget_buffer_init(&buf, sbuf, sizeof(sbuf)); + wget_buffer_deinit(&buf); + + // testing buffer on stack, using initial stack memory + // with resizing + + wget_buffer_init(&buf, sbuf, sizeof(sbuf)); + _test_buffer(&buf, "Test 1"); + wget_buffer_deinit(&buf); + + // testing buffer on stack, using initial heap memory + // without resizing + + wget_buffer_init(&buf, NULL, 16); + wget_buffer_deinit(&buf); + + // testing buffer on stack, using initial heap memory + // with resizing + + wget_buffer_init(&buf, NULL, 16); + _test_buffer(&buf, "Test 2"); + wget_buffer_deinit(&buf); + + // testing buffer on heap, using initial stack memory + // without resizing + + bufp = wget_buffer_init(NULL, sbuf, sizeof(sbuf)); + wget_buffer_deinit(bufp); + + bufp = wget_buffer_init(NULL, sbuf, sizeof(sbuf)); + wget_buffer_free(&bufp); + + // testing buffer on heap, using initial stack memory + // with resizing + + bufp = wget_buffer_init(NULL, sbuf, sizeof(sbuf)); + _test_buffer(bufp, "Test 3"); + wget_buffer_deinit(bufp); + + bufp = wget_buffer_init(NULL, sbuf, sizeof(sbuf)); + _test_buffer(bufp, "Test 4"); + wget_buffer_free(&bufp); + + // testing buffer on heap, using initial heap memory + // without resizing + + bufp = wget_buffer_alloc(16); + wget_buffer_free(&bufp); + + // testing buffer on heap, using initial heap memory + // with resizing + + bufp = wget_buffer_alloc(16); + _test_buffer(bufp, "Test 5"); + wget_buffer_free(&bufp); + + // check that appending works + + wget_buffer_init(&buf, sbuf, sizeof(sbuf)); + wget_buffer_strcpy(&buf, "A"); + wget_buffer_strcat(&buf, "B"); + wget_buffer_memcat(&buf, "C", 1); + wget_buffer_memset_append(&buf, 'D', 1); + wget_buffer_printf_append2(&buf, "%s", "E"); + if (!strcmp(buf.data, "ABCDE")) + ok++; + else { + failed++; + info_printf("test_buffer.append: got %s (expected %s)\n", buf.data, "ABCDE"); + } + wget_buffer_deinit(&buf); + + // test wget_buffer_trim() + + wget_buffer_init(&buf, sbuf, sizeof(sbuf)); + for (int mid_ws = 0; mid_ws <= 2; mid_ws++) { + char expected[16]; + snprintf(expected, sizeof(expected), "x%.*sy", mid_ws, " "); + + for (int lead_ws = 0; lead_ws <= 2; lead_ws++) { + for (int trail_ws = 0; trail_ws <= 2; trail_ws++) { + wget_buffer_printf2(&buf, "%.*sx%.*sy%.*s", lead_ws, " ", mid_ws, " ", trail_ws, " "); + wget_buffer_trim(&buf); + if (!strcmp(buf.data, expected)) + ok++; + else { + failed++; + info_printf("test_buffer_trim: got '%s' (expected '%s') (%d, %d, %d)\n", buf.data, expected, lead_ws, mid_ws, trail_ws); + } + } + } + } + wget_buffer_deinit(&buf); +} + +static void test_buffer_printf(void) +{ + char buf_static[32]; + wget_buffer_t buf; + + // testing buffer_printf() by comparing it with C standard function sprintf() + + static const char *zero_padded[] = { "", "0" }; + static const char *left_adjust[] = { "", "-" }; + static const long long number[] = { 0, 1LL, -1LL, 10LL, -10LL, 18446744073709551615ULL }; + static const char *modifier[] = { "", "h", "hh", "l", "ll", "z" }; // %L... won't work on OpenBSD5.0 + static const char *conversion[] = { "d", "i", "u", "o", "x", "X" }; + char fmt[32], result[64], string[32]; + size_t z, a, it, n, c, m; + int width, precision; + + wget_buffer_init(&buf, buf_static, sizeof(buf_static)); + + wget_buffer_printf2(&buf, "%s://%s", "http", "host"); + if (strcmp("http://host", buf.data)) { + failed++; + info_printf("%s: Failed with format ('%%s://%%s','http','host'): '%s' != 'http://host'\n", __func__, buf.data); + return; + } else + ok++; + + for (z = 0; z < countof(zero_padded); z++) { + for (a = 0; a < countof(left_adjust); a++) { + for (width = -1; width < 12; width++) { + for (precision = -1; precision < 12; precision++) { + + // testing %s stuff + // Solaris' sprintf uses spaces instead of 0s for e.g. %03s padding + + if (width == -1) { + if (precision == -1) { + sprintf(fmt,"abc%%%s%ssxyz", left_adjust[a], zero_padded[z]); + } else { + sprintf(fmt,"abc%%%s%s.%dsxyz", left_adjust[a], zero_padded[z], precision); + } + } else { + if (precision == -1) { + sprintf(fmt,"abc%%%s%s%dsxyz", left_adjust[a], zero_padded[z], width); + } else { + sprintf(fmt,"abc%%%s%s%d.%dsxyz", left_adjust[a], zero_padded[z], width, precision); + } + } + + for (it = 0; it < sizeof(string); it++) { + memset(string, 'a', it); + string[it] = 0; + +#if defined __clang__ || __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 5) + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wformat-nonliteral" +#endif + sprintf(result, fmt, string); + wget_buffer_printf2(&buf, fmt, string); +#if defined __clang__ || __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 5) + #pragma GCC diagnostic pop +#endif + if (strcmp(result, buf.data)) { + failed++; + info_printf("%s: Failed with format ('%s','%s'): '%s' != '%s'\n", __func__, fmt, string, buf.data, result); + return; + } else { + // info_printf("%s: format ('%s','%s'): '%s' == '%s'\n", __func__, fmt, string, buf.data, result); + ok++; + } + } + + if (width == -1) { + if (precision == -1) { + sprintf(fmt,"%%%s%ss", left_adjust[a], zero_padded[z]); + } else { + sprintf(fmt,"%%%s%s.*s", left_adjust[a], zero_padded[z]); + } + } else { + if (precision == -1) { + sprintf(fmt,"%%%s%s*s", left_adjust[a], zero_padded[z]); + } else { + sprintf(fmt,"%%%s%s*.*s", left_adjust[a], zero_padded[z]); + } + } + + for (it = 0; it < sizeof(string); it++) { + memset(string, 'a', it); + string[it] = 0; + +#if defined __clang__ || __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 5) + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wformat-nonliteral" +#endif + if (width == -1) { + if (precision == -1) { + sprintf(result, fmt, string); + wget_buffer_printf2(&buf, fmt, string); + } else { + sprintf(result, fmt, precision, string); + wget_buffer_printf2(&buf, fmt, precision, string); + } + } else { + if (precision == -1) { + sprintf(result, fmt, width, string); + wget_buffer_printf2(&buf, fmt, width, string); + } else { + sprintf(result, fmt, width, precision, string); + wget_buffer_printf2(&buf, fmt, width, precision, string); + } + } +#if defined __clang__ || __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 5) + #pragma GCC diagnostic pop +#endif + + if (strcmp(result, buf.data)) { + failed++; + info_printf("%s: Failed with format ('%s','%s'): '%s' != '%s'\n", __func__, fmt, string, buf.data, result); + return; + } else { + // info_printf("%s: format ('%s','%s'): '%s' == '%s'\n", __func__, fmt, string, buf.data, result); + ok++; + } + } + + // testing integer stuff + + for (m = 0; m < countof(modifier); m++) { + for (c = 0; c < countof(conversion); c++) { + if (width == -1) { + if (precision == -1) { + sprintf(fmt,"%%%s%s%s%s", left_adjust[a], zero_padded[z], modifier[m], conversion[c]); + } else { + sprintf(fmt,"%%%s%s.%d%s%s", left_adjust[a], zero_padded[z], precision, modifier[m], conversion[c]); + } + } else { + if (precision == -1) { + sprintf(fmt,"%%%s%s%d%s%s", left_adjust[a], zero_padded[z], width, modifier[m], conversion[c]); + } else { + sprintf(fmt,"%%%s%s%d.%d%s%s", left_adjust[a], zero_padded[z], width, precision, modifier[m], conversion[c]); + } + } + + for (n = 0; n < countof(number); n++) { +#if defined __clang__ || __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 5) + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wformat-nonliteral" +#endif + sprintf(result, fmt, number[n]); + wget_buffer_printf2(&buf, fmt, number[n]); +#if defined __clang__ || __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 5) + #pragma GCC diagnostic pop +#endif + + if (strcmp(result, buf.data)) { + failed++; + info_printf("%s: Failed with format ('%s','%lld'): '%s' != '%s'\n", __func__, fmt, number[n], buf.data, result); +// return; + } else { + // info_printf("%s: format ('%s','%lld'): '%s' == '%s'\n", __func__, fmt, number[n], buf.data, result); + ok++; + } + } + } + } + } + } + } + } + + wget_buffer_deinit(&buf); +} + +static void test_iri_parse(void) +{ + const struct iri_test_data { + const char + *uri, + *display, + *scheme, + *userinfo, + *password, + *host, + *port, + *path, + *query, + *fragment; + } test_data[] = { + { "1.2.3.4", NULL, WGET_IRI_SCHEME_HTTP, NULL, NULL, "1.2.3.4", NULL, NULL, NULL, NULL}, + { "1.2.3.4:987", NULL, WGET_IRI_SCHEME_HTTP, NULL, NULL, "1.2.3.4", "987", NULL, NULL, NULL}, + { "//example.com/thepath", NULL, WGET_IRI_SCHEME_HTTP, NULL, NULL, "example.com", NULL, "thepath", NULL, NULL}, + // { "///thepath", NULL, WGET_IRI_SCHEME_HTTP, NULL, NULL, NULL, NULL, "thepath", NULL, NULL}, + { "example.com", NULL, WGET_IRI_SCHEME_HTTP, NULL, NULL, "example.com", NULL, NULL, NULL, NULL}, + { "example.com:555", NULL, WGET_IRI_SCHEME_HTTP, NULL, NULL, "example.com", "555", NULL, NULL, NULL}, + { "http://example.com", NULL, WGET_IRI_SCHEME_HTTP, NULL, NULL, "example.com", NULL, NULL, NULL, NULL}, + { "http://example.com:", NULL, WGET_IRI_SCHEME_HTTP, NULL, NULL, "example.com", NULL, NULL, NULL, NULL}, + { "http://example.com:/", NULL, WGET_IRI_SCHEME_HTTP, NULL, NULL, "example.com", NULL, "", NULL, NULL}, + { "http://example.com:80/", NULL, WGET_IRI_SCHEME_HTTP, NULL, NULL, "example.com", NULL, "", NULL, NULL}, + { "https://example.com", NULL, WGET_IRI_SCHEME_HTTPS, NULL, NULL, "example.com", NULL, NULL, NULL, NULL}, + { "https://example.com:443", NULL, WGET_IRI_SCHEME_HTTPS, NULL, NULL, "example.com", NULL, NULL, NULL, NULL}, + { "https://example.com:444", NULL, WGET_IRI_SCHEME_HTTPS, NULL, NULL, "example.com", "444", NULL, NULL, NULL}, + { "http://example.com:80", NULL, WGET_IRI_SCHEME_HTTP, NULL, NULL, "example.com", NULL, NULL, NULL, NULL}, + { "http://example.com:81", NULL, WGET_IRI_SCHEME_HTTP, NULL, NULL, "example.com", "81", NULL, NULL, NULL}, + { "http://example.com/index.html", NULL, WGET_IRI_SCHEME_HTTP, NULL, NULL, "example.com", NULL, "index.html", NULL, NULL}, + { "http://example.com/index.html?query#frag", NULL, WGET_IRI_SCHEME_HTTP, NULL, NULL, "example.com", NULL, "index.html", "query", "frag"}, + { "http://example.com/index.html?#", NULL, WGET_IRI_SCHEME_HTTP, NULL, NULL, "example.com", NULL, "index.html", "", ""}, + { "碼標準萬國碼.com", NULL, WGET_IRI_SCHEME_HTTP, NULL, NULL, "xn--9cs565brid46mda086o.com", NULL, NULL, NULL, NULL}, + // { "ftp://cnn.example.com&story=breaking_news@10.0.0.1/top_story.htm", NULL,"ftp",NULL,NULL,"cnn.example.com",NULL,NULL,"story=breaking_news@10.0.0.1/top_story.htm",NULL } + { "ftp://cnn.example.com?story=breaking_news@10.0.0.1/top_story.htm", NULL, "ftp", NULL, NULL, "cnn.example.com", NULL, NULL, "story=breaking_news@10.0.0.1/top_story.htm", NULL}, +// { "site;sub:.html", NULL, WGET_IRI_SCHEME_HTTP, NULL, NULL, "site", NULL, ";sub:.html", NULL, NULL}, + }; + unsigned it; + + for (it = 0; it < countof(test_data); it++) { + const struct iri_test_data *t = &test_data[it]; + wget_iri_t *iri = wget_iri_parse(t->uri, "utf-8"); + + if (wget_strcmp(iri->display, t->display) + || wget_strcmp(iri->scheme, t->scheme) + || wget_strcmp(iri->userinfo, t->userinfo) + || wget_strcmp(iri->password, t->password) + || wget_strcmp(iri->host, t->host) + || wget_strcmp(iri->port, t->port) + || wget_strcmp(iri->path, t->path) + || wget_strcmp(iri->query, t->query) + || wget_strcmp(iri->fragment, t->fragment)) + { + failed++; + printf("IRI test #%u failed:\n", it + 1); + printf(" [%s]\n", iri->uri); + printf(" display %s (expected %s)\n", iri->display, t->display); + printf(" scheme %s (expected %s)\n", iri->scheme, t->scheme); + printf(" user %s (expected %s)\n", iri->userinfo, t->userinfo); + printf(" host %s (expected %s)\n", iri->host, t->host); + printf(" port %s (expected %s)\n", iri->port, t->port); + printf(" path %s (expected %s)\n", iri->path, t->path); + printf(" query %s (expected %s)\n", iri->query, t->query); + printf(" fragment %s (expected %s)\n", iri->fragment, t->fragment); + printf("\n"); + } else { + ok++; + } + + wget_iri_free(&iri); + } +} + +static void test_iri_relative_to_absolute(void) +{ + static const struct iri_test_data { + const char + *base, + *relative, + *result; + } test_data[] = { +#define H1 "http://x.tld" + { H1, "", H1"/" }, + { H1, ".", H1"/" }, + { H1, "./", H1"/" }, + { H1, "..", H1"/" }, + { H1, "../", H1"/" }, + { H1, "foo", H1"/foo" }, + { H1, "foo/bar", H1"/foo/bar" }, + { H1, "foo///bar", H1"/foo/bar" }, + { H1, "foo/.", H1"/foo/" }, + { H1, "foo/./", H1"/foo/" }, + { H1, "foo./", H1"/foo./" }, + { H1, "foo/../bar", H1"/bar" }, + { H1, "foo/../bar/", H1"/bar/" }, + { H1, "foo/bar/..", H1"/foo/" }, + { H1, "foo/bar/../x", H1"/foo/x" }, + { H1, "foo/bar/../x/", H1"/foo/x/" }, + { H1, "foo/..", H1"/" }, + { H1, "foo/../..", H1"/" }, + { H1, "foo/../../..", H1"/" }, + { H1, "foo/../../bar/../../baz", H1"/baz" }, + { H1, "a/b/../../c", H1"/c" }, + { H1, "./a/../b", H1"/b" }, + { H1, "/", H1"/" }, + { H1, "/.", H1"/" }, + { H1, "/./", H1"/" }, + { H1, "/..", H1"/" }, + { H1, "/../", H1"/" }, + { H1, "/foo", H1"/foo" }, + { H1, "/foo/bar", H1"/foo/bar" }, + { H1, "/foo///bar", H1"/foo/bar" }, + { H1, "/foo/.", H1"/foo/" }, + { H1, "/foo/./", H1"/foo/" }, + { H1, "/foo./", H1"/foo./" }, + { H1, "/foo/../bar", H1"/bar" }, + { H1, "/foo/../bar/", H1"/bar/" }, + { H1, "/foo/bar/..", H1"/foo/" }, + { H1, "/foo/bar/../x", H1"/foo/x" }, + { H1, "/foo/bar/../x/", H1"/foo/x/" }, + { H1, "/foo/..", H1"/" }, + { H1, "/foo/../..", H1"/" }, + { H1, "/foo/../../..", H1"/" }, + { H1, "/foo/../../bar/../../baz", H1"/baz" }, + { H1, "/a/b/../../c", H1"/c" }, + { H1, "/./a/../b", H1"/b" }, + { H1, ".x", H1"/.x" }, + { H1, "..x", H1"/..x" }, + { H1, "foo/.x", H1"/foo/.x" }, + { H1, "foo/bar/.x", H1"/foo/bar/.x" }, + { H1, "foo/..x", H1"/foo/..x" }, + { H1, "foo/bar/..x", H1"/foo/bar/..x" }, + { H1, "/x.php?y=ftp://example.com/&z=1_2", H1"/x.php?y=ftp://example.com/&z=1_2" }, + { H1, "//x.y.com/", "http://x.y.com/" }, + { H1, "http://x.y.com/", "http://x.y.com/" }, +// { H1, "site;sub:.html", H1"/site;sub:.html" }, +#undef H1 +#define H1 "http://x.tld/" + { H1, "", H1"" }, + { H1, ".", H1"" }, + { H1, "./", H1"" }, + { H1, "..", H1"" }, + { H1, "../", H1"" }, + { H1, "foo", H1"foo" }, + { H1, "foo/bar", H1"foo/bar" }, + { H1, "foo///bar", H1"foo/bar" }, + { H1, "foo/.", H1"foo/" }, + { H1, "foo/./", H1"foo/" }, + { H1, "foo./", H1"foo./" }, + { H1, "foo/../bar", H1"bar" }, + { H1, "foo/../bar/", H1"bar/" }, + { H1, "foo/bar/..", H1"foo/" }, + { H1, "foo/bar/../x", H1"foo/x" }, + { H1, "foo/bar/../x/", H1"foo/x/" }, + { H1, "foo/..", H1"" }, + { H1, "foo/../..", H1"" }, + { H1, "foo/../../..", H1"" }, + { H1, "foo/../../bar/../../baz", H1"baz" }, + { H1, "a/b/../../c", H1"c" }, + { H1, "./a/../b", H1"b" }, + { H1, "/", H1"" }, + { H1, "/.", H1"" }, + { H1, "/./", H1"" }, + { H1, "/..", H1"" }, + { H1, "/../", H1"" }, + { H1, "/foo", H1"foo" }, + { H1, "/foo/bar", H1"foo/bar" }, + { H1, "/foo///bar", H1"foo/bar" }, + { H1, "/foo/.", H1"foo/" }, + { H1, "/foo/./", H1"foo/" }, + { H1, "/foo./", H1"foo./" }, + { H1, "/foo/../bar", H1"bar" }, + { H1, "/foo/../bar/", H1"bar/" }, + { H1, "/foo/bar/..", H1"foo/" }, + { H1, "/foo/bar/../x", H1"foo/x" }, + { H1, "/foo/bar/../x/", H1"foo/x/" }, + { H1, "/foo/..", H1"" }, + { H1, "/foo/../..", H1"" }, + { H1, "/foo/../../..", H1"" }, + { H1, "/foo/../../bar/../../baz", H1"baz" }, + { H1, "/a/b/../../c", H1"c" }, + { H1, "/./a/../b", H1"b" }, + { H1, ".x", H1".x" }, + { H1, "..x", H1"..x" }, + { H1, "foo/.x", H1"foo/.x" }, + { H1, "foo/bar/.x", H1"foo/bar/.x" }, + { H1, "foo/..x", H1"foo/..x" }, + { H1, "foo/bar/..x", H1"foo/bar/..x" }, + { H1, "/x.php?y=ftp://example.com/&z=1_2", H1"x.php?y=ftp://example.com/&z=1_2" }, + { H1, "//x.y.com/", "http://x.y.com/" }, + { H1, "http://x.y.com/", "http://x.y.com/" }, +#undef H1 +#define H1 "http://x.tld/file" +#define R1 "http://x.tld/" + { H1, "", R1"" }, + { H1, ".", R1"" }, + { H1, "./", R1"" }, + { H1, "..", R1"" }, + { H1, "../", R1"" }, + { H1, "foo", R1"foo" }, + { H1, "foo/bar", R1"foo/bar" }, + { H1, "foo///bar", R1"foo/bar" }, + { H1, "foo/.", R1"foo/" }, + { H1, "foo/./", R1"foo/" }, + { H1, "foo./", R1"foo./" }, + { H1, "foo/../bar", R1"bar" }, + { H1, "foo/../bar/", R1"bar/" }, + { H1, "foo/bar/..", R1"foo/" }, + { H1, "foo/bar/../x", R1"foo/x" }, + { H1, "foo/bar/../x/", R1"foo/x/" }, + { H1, "foo/..", R1"" }, + { H1, "foo/../..", R1"" }, + { H1, "foo/../../..", R1"" }, + { H1, "foo/../../bar/../../baz", R1"baz" }, + { H1, "a/b/../../c", R1"c" }, + { H1, "./a/../b", R1"b" }, + { H1, "/", R1"" }, + { H1, "/.", R1"" }, + { H1, "/./", R1"" }, + { H1, "/..", R1"" }, + { H1, "/../", R1"" }, + { H1, "/foo", R1"foo" }, + { H1, "/foo/bar", R1"foo/bar" }, + { H1, "/foo///bar", R1"foo/bar" }, + { H1, "/foo/.", R1"foo/" }, + { H1, "/foo/./", R1"foo/" }, + { H1, "/foo./", R1"foo./" }, + { H1, "/foo/../bar", R1"bar" }, + { H1, "/foo/../bar/", R1"bar/" }, + { H1, "/foo/bar/..", R1"foo/" }, + { H1, "/foo/bar/../x", R1"foo/x" }, + { H1, "/foo/bar/../x/", R1"foo/x/" }, + { H1, "/foo/..", R1"" }, + { H1, "/foo/../..", R1"" }, + { H1, "/foo/../../..", R1"" }, + { H1, "/foo/../../bar/../../baz", R1"baz" }, + { H1, "/a/b/../../c", R1"c" }, + { H1, "/./a/../b", R1"b" }, + { H1, ".x", R1".x" }, + { H1, "..x", R1"..x" }, + { H1, "foo/.x", R1"foo/.x" }, + { H1, "foo/bar/.x", R1"foo/bar/.x" }, + { H1, "foo/..x", R1"foo/..x" }, + { H1, "foo/bar/..x", R1"foo/bar/..x" }, + { H1, "/x.php?y=ftp://example.com/&z=1_2", R1"x.php?y=ftp://example.com/&z=1_2" }, + { H1, "//x.y.com/", "http://x.y.com/" }, + { H1, "http://x.y.com/", "http://x.y.com/" }, +#undef H1 +#undef R1 +#define H1 "http://x.tld/dir/" +#define R1 "http://x.tld/" + { H1, "", H1"" }, + { H1, ".", H1"" }, + { H1, "./", H1"" }, + { H1, "..", R1"" }, + { H1, "../", R1"" }, + { H1, "foo", H1"foo" }, + { H1, "foo/bar", H1"foo/bar" }, + { H1, "foo///bar", H1"foo/bar" }, + { H1, "foo/.", H1"foo/" }, + { H1, "foo/./", H1"foo/" }, + { H1, "foo./", H1"foo./" }, + { H1, "foo/../bar", H1"bar" }, + { H1, "foo/../bar/", H1"bar/" }, + { H1, "foo/bar/..", H1"foo/" }, + { H1, "foo/bar/../x", H1"foo/x" }, + { H1, "foo/bar/../x/", H1"foo/x/" }, + { H1, "foo/..", H1"" }, + { H1, "foo/../..", R1"" }, + { H1, "foo/../../..", R1"" }, + { H1, "foo/../../bar/../../baz", R1"baz" }, + { H1, "a/b/../../c", H1"c" }, + { H1, "./a/../b", H1"b" }, + { H1, "/", R1"" }, + { H1, "/.", R1"" }, + { H1, "/./", R1"" }, + { H1, "/..", R1"" }, + { H1, "/../", R1"" }, + { H1, "/foo", R1"foo" }, + { H1, "/foo/bar", R1"foo/bar" }, + { H1, "/foo///bar", R1"foo/bar" }, + { H1, "/foo/.", R1"foo/" }, + { H1, "/foo/./", R1"foo/" }, + { H1, "/foo./", R1"foo./" }, + { H1, "/foo/../bar", R1"bar" }, + { H1, "/foo/../bar/", R1"bar/" }, + { H1, "/foo/bar/..", R1"foo/" }, + { H1, "/foo/bar/../x", R1"foo/x" }, + { H1, "/foo/bar/../x/", R1"foo/x/" }, + { H1, "/foo/..", R1"" }, + { H1, "/foo/../..", R1"" }, + { H1, "/foo/../../..", R1"" }, + { H1, "/foo/../../bar/../../baz", R1"baz" }, + { H1, "/a/b/../../c", R1"c" }, + { H1, "/./a/../b", R1"b" }, + { H1, ".x", H1".x" }, + { H1, "..x", H1"..x" }, + { H1, "foo/.x", H1"foo/.x" }, + { H1, "foo/bar/.x", H1"foo/bar/.x" }, + { H1, "foo/..x", H1"foo/..x" }, + { H1, "foo/bar/..x", H1"foo/bar/..x" }, + { H1, "/x.php?y=ftp://example.com/&z=1_2", R1"x.php?y=ftp://example.com/&z=1_2" }, + { H1, "//x.y.com/", "http://x.y.com/" }, + { H1, "http://x.y.com/", "http://x.y.com/" } +#undef H1 +#undef R1 + }; + unsigned it; + char uri_buf_static[32]; // use a size that forces allocation in some cases + wget_buffer_t *uri_buf = wget_buffer_init(NULL, uri_buf_static, sizeof(uri_buf_static)); + wget_iri_t *base; + + for (it = 0; it < countof(test_data); it++) { + const struct iri_test_data *t = &test_data[it]; + + base = wget_iri_parse(t->base, "utf-8"); + wget_iri_relative_to_abs(base, t->relative, strlen(t->relative), uri_buf); + + if (!strcmp(uri_buf->data, t->result)) + ok++; + else { + failed++; + info_printf("Failed [%u]: %s+%s -> %s (expected %s)\n", it, t->base, t->relative, uri_buf->data, t->result); + } + + wget_iri_free(&base); + } + + wget_buffer_free(&uri_buf); +} + +static void test_iri_compare(void) +{ + static const struct iri_test_data { + const char + *url1, + *url2; + int + result; + } test_data[] = { + { "http://abc.com", "http://abc.com/", -1}, // different, some web servers redirect ... to .../ due to normalization issues + { "http://abc.com", "http://abc.com:", 0}, + { "http://abc.com", "http://abc.com:/", -1}, + { "http://abc.com", "http://abc.com:80/", -1}, + { "http://abc.com", "http://abc.com:80//", -1}, + // { "http://äöü.com", "http://ÄÖÜ.com:80//", 0}, + { "http://abc.com:80/~smith/home.html", "http://abc.com/~smith/home.html", 0}, + { "http://abc.com:80/~smith/home.html", "http://ABC.com/~smith/home.html", 0}, + { "http://abc.com:80/~smith/home.html", "http://ABC.com/%7Esmith/home.html", 0}, + { "http://abc.com:80/~smith/home.html", "http://ABC.com/%7esmith/home.html", 0}, + { "http://ABC.com/%7esmith/home.html", "http://ABC.com/%7Esmith/home.html", 0}, + { "http://ABC.com/%7esmith/home.html", "http://ACB.com/%7Esmith/home.html", -1} + }; + unsigned it; + int n; + + for (it = 0; it < countof(test_data); it++) { + const struct iri_test_data *t = &test_data[it]; + wget_iri_t *iri1 = wget_iri_parse(t->url1, "utf-8"); + wget_iri_t *iri2 = wget_iri_parse(t->url2, "utf-8"); + + n = wget_iri_compare(iri1, iri2); + if (n < -1) n = -1; + else if (n > 1) n = 1; + + if (n == t->result) + ok++; + else { + failed++; + info_printf("Failed [%u]: compare(%s,%s) -> %d (expected %d)\n", it, t->url1, t->url2, n, t->result); + printf(" display %s / %s\n", iri1->display, iri2->display); + printf(" scheme %s / %s\n", iri1->scheme, iri2->scheme); + printf(" user %s / %s\n", iri1->userinfo, iri2->userinfo); + printf(" host %s / %s\n", iri1->host, iri2->host); + printf(" port %s / %s\n", iri1->port, iri2->port); + printf(" path %s / %s\n", iri1->path, iri2->path); + printf(" query %s / %s\n", iri1->query, iri2->query); + printf(" fragment %s / %s\n", iri1->fragment, iri2->fragment); + printf("\n"); + } + + wget_iri_free(&iri2); + wget_iri_free(&iri1); + } +} + +/* +static void _css_dump_charset(G_GNUC_WGET_UNUSED void *user_ctx, const char *encoding, size_t len) +{ + debug_printf(_("URI content encoding = '%.*s'\n"), (int)len, encoding); +} + +static void _css_dump_uri(G_GNUC_WGET_UNUSED void *user_ctx, const char *url, size_t len, G_GNUC_WGET_UNUSED size_t pos) +{ + debug_printf("*** %zu '%.*s'\n", len, (int)len, url); +} +*/ + +static void test_parser(void) +{ + DIR *dirp; + struct dirent *dp; + const char *ext; + char fname[128]; + int xml = 0, html = 0, css = 0; + + // test the XML / HTML parser, you should start the test with valgrind + // to detect memory faults + if ((dirp = opendir(SRCDIR "/files")) != NULL) { + while ((dp = readdir(dirp)) != NULL) { + if (*dp->d_name == '.') continue; + if ((ext = strrchr(dp->d_name, '.'))) { + snprintf(fname, sizeof(fname), SRCDIR "/files/%s", dp->d_name); + if (!wget_strcasecmp_ascii(ext, ".xml")) { + info_printf("parsing %s\n", fname); + wget_xml_parse_file(fname, NULL, NULL, 0); + xml++; + } +/* else if (!wget_strcasecmp_ascii(ext, ".html")) { + info_printf("parsing %s\n", fname); + wget_html_parse_file(fname, NULL, NULL, 0); + html++; + } + else if (!wget_strcasecmp_ascii(ext, ".css")) { + info_printf("parsing %s\n", fname); + wget_css_parse_file(fname, _css_dump_uri, _css_dump_charset, NULL); + css++; + } */ + } + } + closedir(dirp); + } + + info_printf("%d XML, %d HTML and %d CSS files parsed\n", xml, html, css); +} + +static void test_cookies(void) +{ + static const struct test_data { + const char + *uri, + *set_cookie, + *name, *value, *domain, *path, *expires; + unsigned int + domain_dot : 1, // for compatibility with Netscape cookie format + normalized : 1, + persistent : 1, + host_only : 1, + secure_only : 1, // cookie should be used over secure connections only (TLS/HTTPS) + http_only : 1; // just use the cookie via HTTP/HTTPS protocol + int + result, + psl_result; + } test_data[] = { + { // allowed cookie + "www.example.com", + "ID=65=abcd; expires=Tuesday, 07-May-2013 07:48:53 GMT; path=/; domain=.example.com; HttpOnly", + "ID", "65=abcd", "example.com", "/", "Tue, 07 May 2013 07:48:53 GMT", + 1, 1, 1, 0, 0, 1, + 0, 0 + }, + { // allowed cookie ANSI C's asctime format + "www.example.com", + "ID=65=abcd; expires=Tue May 07 07:48:53 2013; path=/; domain=.example.com", + "ID", "65=abcd", "example.com", "/", "Tue, 07 May 2013 07:48:53 GMT", + 1, 1, 1, 0, 0, 0, + 0, 0 + }, + { // allowed cookie without path + "www.example.com", + "ID=65=abcd; expires=Tue, 07-May-2013 07:48:53 GMT; domain=.example.com", + "ID", "65=abcd", "example.com", "/", "Tue, 07 May 2013 07:48:53 GMT", + 1, 1, 1, 0, 0, 0, + 0, 0 + }, + { // allowed cookie without domain + "www.example.com", + "ID=65=abcd; expires=Tue, 07-May-2013 07:48:53 GMT; path=/", + "ID", "65=abcd", "www.example.com", "/", "Tue, 07 May 2013 07:48:53 GMT", + 0, 1, 1, 1, 0, 0, + 0, 0 + }, + { // allowed cookie without domain, path and expires + "www.example.com", + "ID=65=abcd", + "ID", "65=abcd", "www.example.com", "/", "Tue, 07 May 2013 07:48:53 GMT", + 0, 1, 0, 1, 0, 0, + 0, 0 + }, + { // illegal cookie + "www.example.com", + "ID=65=abcd; expires=Tue, 07-May-2013 07:48:53 GMT; path=/; domain=.example.org", + "ID", "65=abcd", "example.org", "/", "Tue, 07 May 2013 07:48:53 GMT", + 1, 0, 1, 0, 0, 0, + -1, 0 + }, +#ifdef WITH_LIBPSL + { // supercookie, accepted by normalization (rule 'com') but not by wget_cookie_check_psl()) + "www.example.com", + "ID=65=abcd; expires=Mon, 29-Feb-2016 07:48:54 GMT; path=/; domain=.com; HttpOnly; Secure", + "ID", "65=abcd", "com", "/", "Mon, 29 Feb 2016 07:48:54 GMT", + 1, 0, 1, 0, 1, 1, + 0, -1 + }, + { // supercookie, accepted by normalization (rule '*.ar') but not by wget_cookie_check_psl()) + "www.sa.gov.au", + "ID=65=abcd; expires=Tue, 29-Feb-2000 07:48:55 GMT; path=/; domain=.sa.gov.au", + "ID", "65=abcd", "sa.gov.au", "/", "Tue, 29 Feb 2000 07:48:55 GMT", + 1, 0, 1, 0, 0, 0, + 0, -1 + }, +#endif + { // exception rule '!educ.ar', accepted by normalization + "www.educ.ar", + "ID=65=abcd; path=/; domain=.educ.ar", + "ID", "65=abcd", "educ.ar", "/", NULL, + 1, 1, 0, 0, 0, 0, + 0, 0 + }, + }; + wget_cookie_t cookie; + wget_cookie_db_t *cookies; + wget_iri_t *iri; + unsigned it; + int result, result_psl; + + cookies = wget_cookie_db_init(NULL); + wget_cookie_db_load_psl(cookies, NULL); + + for (it = 0; it < countof(test_data); it++) { + const struct test_data *t = &test_data[it]; + char thedate[32], *header; + + iri = wget_iri_parse(t->uri, "utf-8"); + wget_http_parse_setcookie(t->set_cookie, &cookie); + if ((result = wget_cookie_normalize(iri, &cookie)) != t->result) { + failed++; + info_printf("Failed [%u]: normalize_cookie(%s) -> %d (expected %d)\n", it, t->set_cookie, result, t->result); + wget_cookie_deinit(&cookie); + goto next; + } else { + if ((result_psl = wget_cookie_check_psl(cookies, &cookie)) != t->psl_result) { + failed++; + info_printf("Failed [%u]: PSL check(%s) -> %d (expected %d)\n", it, t->set_cookie, result_psl, t->psl_result); + } + wget_cookie_deinit(&cookie); + goto next; + } + + if (cookie.expires) { + wget_http_print_date(cookie.expires, thedate, sizeof(thedate)); + if (strcmp(thedate, t->expires)) { + failed++; + info_printf("Failed [%u]: expires mismatch: '%s' != '%s' (time_t %lld)\n", it, thedate, t->expires, (long long)cookie.expires); + wget_cookie_deinit(&cookie); + goto next; + } + } + + if (strcmp(cookie.name, t->name) || + strcmp(cookie.value, t->value) || + strcmp(cookie.domain, t->domain) || + strcmp(cookie.path, t->path) || + cookie.domain_dot != t->domain_dot || + cookie.normalized != t->normalized || + cookie.persistent != t->persistent || + cookie.host_only != t->host_only || + cookie.secure_only != t->secure_only || + cookie.http_only != t->http_only) + { + failed++; + + info_printf("Failed [%u]: cookie (%s) differs:\n", it, t->set_cookie); + if (strcmp(cookie.name, t->name)) + info_printf(" name %s (expected %s)\n", cookie.name, t->name); + if (strcmp(cookie.value, t->value)) + info_printf(" value %s (expected %s)\n", cookie.value, t->value); + if (strcmp(cookie.domain, t->domain)) + info_printf(" domain %s (expected %s)\n", cookie.domain, t->domain); + if (strcmp(cookie.path, t->path)) + info_printf(" path %s (expected %s)\n", cookie.path, t->path); + if (cookie.domain_dot != t->domain_dot) + info_printf(" domain_dot %d (expected %d)\n", cookie.domain_dot, t->domain_dot); + if (cookie.normalized != t->normalized) + info_printf(" normalized %d (expected %d)\n", cookie.normalized, t->normalized); + if (cookie.persistent != t->persistent) + info_printf(" persistent %d (expected %d)\n", cookie.persistent, t->persistent); + if (cookie.host_only != t->host_only) + info_printf(" host_only %d (expected %d)\n", cookie.host_only, t->host_only); + if (cookie.secure_only != t->secure_only) + info_printf(" secure_only %d (expected %d)\n", cookie.secure_only, t->secure_only); + if (cookie.http_only != t->http_only) + info_printf(" http_only %d (expected %d)\n", cookie.http_only, t->http_only); + + wget_cookie_deinit(&cookie); + goto next; + } + + wget_cookie_store_cookie(cookies, &cookie); + + info_printf("%s\n", header = wget_cookie_create_request_header(cookies, iri)); + xfree(header); + + ok++; + +next: + wget_iri_free(&iri); + } + + wget_cookie_db_free(&cookies); +} + +static void test_hsts(void) +{ + static const struct hsts_db_data { + const char * + host; + int + port; + const char * + hsts_params; + } hsts_db_data[] = { + { "www.example.com", 443, "max-age=14400; includeSubDomains" }, + { "www.example2.com", 443, "max-age=14400" }, + { "www.example2.com", 443, "max-age=0" }, // this removes the previous entry + }; + static const struct hsts_data { + const char * + host; + int + port; + int + result; + } hsts_data[] = { + { "www.example.com", 443, 1 }, // exact match + { "ftp.example.com", 443, 0 }, + { "example.com", 443, 0 }, + { "sub.www.example.com", 443, 1 }, // subdomain + { "sub1.sub2.www.example.com", 443, 1 }, // subdomain + { "www.example2.com", 443, 0 }, // entry should have been removed due to maxage=0 + { "www.example.com", 80, 0 }, // wrong port + }; + wget_hsts_db_t *hsts_db = wget_hsts_db_init(NULL); + time_t maxage; + char include_subdomains; + int n; + + // fill HSTS database with values + for (unsigned it = 0; it < countof(hsts_db_data); it++) { + const struct hsts_db_data *t = &hsts_db_data[it]; + wget_http_parse_strict_transport_security(t->hsts_params, &maxage, &include_subdomains); + wget_hsts_db_add(hsts_db, wget_hsts_new(t->host, t->port, maxage, include_subdomains)); + } + + // check HSTS database with values + for (unsigned it = 0; it < countof(hsts_data); it++) { + const struct hsts_data *t = &hsts_data[it]; + + n = wget_hsts_host_match(hsts_db, t->host, t->port); + + if (n == t->result) + ok++; + else { + failed++; + info_printf("Failed [%u]: wget_hsts_host_match(%s,%d) -> %d (expected %d)\n", it, t->host, t->port, n, t->result); + } + } + + wget_hsts_db_free(&hsts_db); +} + +static void test_parse_challenge(void) +{ + static const struct test_data { + const char * + input; + const char * + scheme[3]; + } test_data[] = { + { // simplebasic + "Basic realm=\"foo\"", + { "Basic", NULL } + }, + { // simplebasicucase + "BASIC REALM=\"foo\"", + { "Basic", NULL } + }, + { // simplebasicucase + "Basic , realm=\"foo\"", + { "Basic", NULL } + }, + { // + "Basic realm=\"test realm\"", + { "Basic", NULL } + }, + { // + "Basic realm=\"test-äöÜ\"", + { "Basic", NULL } + }, + { // + "Basic realm=\"basic\", Newauth realm=\"newauth\"", + { "Basic", "Newauth", NULL } + }, + }; + + wget_vector_t *challenges; + wget_http_challenge_t *challenge; + + // Testcases found here http://greenbytes.de/tech/tc/httpauth/ + challenges = wget_vector_create(2, 2, NULL); + wget_vector_set_destructor(challenges, (void(*)(void *))wget_http_free_challenge); + + for (unsigned it = 0; it < countof(test_data); it++) { + const struct test_data *t = &test_data[it]; + + wget_http_parse_challenges(t->input, challenges); + for (unsigned nchal = 0; nchal < countof(test_data[0].scheme) && t->scheme[nchal]; nchal++) { + challenge = wget_vector_get(challenges, nchal); + + if (!t->scheme[nchal]) { + if (challenge) { + failed++; + info_printf("Failed [%u]: wget_http_parse_challenges(%s) found %d challenges (expected %d)\n", it, t->input, wget_vector_size(challenges), nchal); + } + break; + } + + if (!challenge) { + failed++; + info_printf("Failed [%u]: wget_http_parse_challenges(%s) did not find enough challenges\n", it, t->input); + break; + } + + if (!wget_strcasecmp_ascii(challenge->auth_scheme, t->scheme[nchal])) { + ok++; + } else { + failed++; + info_printf("Failed [%u]: wget_http_parse_challenges(%s) -> '%s' (expected '%s')\n", it, t->input, challenge->auth_scheme, t->scheme[nchal]); + } + } + + wget_vector_clear(challenges); + } + + wget_http_free_challenges(&challenges); +} + +static void test_utils(void) +{ + int it; + unsigned char src[1]; + char dst1[3], dst2[3]; + + for (int ndst = 1; ndst <= 3; ndst++) { + for (it = 0; it <= 255; it++) { + src[0] = (unsigned char) it; + wget_memtohex(src, 1, dst1, ndst); + snprintf(dst2, ndst, "%02x", src[0]); + if (strcmp(dst1, dst2)) { + info_printf("buffer_to_hex failed: '%s' instead of '%s' (ndst=%d)\n", dst1, dst2, ndst); + failed++; + break; + } + } + + if (it >= 256) + ok++; + else + failed++; + } +} + +static void test_strcasecmp_ascii(void) +{ + static const struct test_data { + const char * + s1; + const char * + s2; + int + result; + } test_data[] = { + { NULL, NULL, 0 }, + { NULL, "x", -1 }, + { "x", NULL, 1 }, + { "Abc", "abc", 0 }, + { "abc", "abc", 0 }, + { "abc", "ab", 'c' }, + { "ab", "abc", -'c' }, + { "abc", "", 'a' }, + { "", "abc", -'a' }, + }; + static const struct test_data2 { + const char * + s1; + const char * + s2; + size_t + n; + int + result; + } test_data2[] = { + { NULL, NULL, 1, 0 }, + { NULL, "x", 1, -1 }, + { "x", NULL, 1, 1 }, + { "Abc", "abc", 2, 0 }, + { "abc", "abc", 3, 0 }, + { "abc", "ab", 2, 0 }, + { "abc", "ab", 3, 'c' }, + { "ab", "abc", 2, 0 }, + { "ab", "abc", 3, -'c' }, + { "abc", "", 1, 'a' }, + { "", "abc", 1, -'a' }, + { "", "abc", 0, 0 }, + }; + + for (unsigned it = 0; it < countof(test_data); it++) { + const struct test_data *t = &test_data[it]; + + int n = wget_strcasecmp_ascii(t->s1, t->s2); + + if (n == t->result) + ok++; + else { + failed++; + info_printf("Failed [%u]: wget_strcasecmp_ascii(%s,%s) -> %d (expected %d)\n", it, t->s1, t->s2, n, t->result); + } + } + + for (unsigned it = 0; it < countof(test_data2); it++) { + const struct test_data2 *t = &test_data2[it]; + + int n = wget_strncasecmp_ascii(t->s1, t->s2, t->n); + + if (n == t->result) + ok++; + else { + failed++; + info_printf("Failed [%u]: wget_strncasecmp_ascii(%s,%s,%zd) -> %d (expected %d)\n", it, t->s1, t->s2, t->n, n, t->result); + } + } + + for (unsigned it = 0; it < 26; it++) { + char s1[8], s2[8]; + + s1[0] = 'a' + it; s1[1] = 0; + s2[0] = 'A' + it; s2[1] = 0; + + if (wget_strcasecmp_ascii(s1, s2) == 0) + ok++; + else { + failed++; + info_printf("Failed: wget_strcasecmp_ascii(%s,%s) != 0\n", s1, s2); + } + + if (wget_strncasecmp_ascii(s1, s2, 1) == 0) + ok++; + else { + failed++; + info_printf("Failed: wget_strncasecmp_ascii(%s,%s) != 0\n", s1, s2); + } + } +} + +struct ENTRY { + const char + *txt; +}; + +static int compare_txt(struct ENTRY *a1, struct ENTRY *a2) +{ + return wget_strcasecmp_ascii(a1->txt, a2->txt); +} + +static void test_vector(void) +{ + struct ENTRY + *tmp, + txt_sorted[5] = { {""}, {"four"}, {"one"}, {"three"}, {"two"} }, + *txt[countof(txt_sorted)]; + wget_vector_t + *v = wget_vector_create(2, -2, (int(*)(const void *, const void *))compare_txt); + unsigned + it; + int + n; + + // copy + for (it = 0; it < countof(txt); it++) + txt[it] = &txt_sorted[it]; + + // shuffle txt + for (it = 0; it < countof(txt); it++) { + n = rand() % countof(txt); + tmp = txt[n]; + txt[n] = txt[it]; + txt[it] = tmp; + } + + for (it = 0; it < countof(txt); it++) { + wget_vector_insert_sorted(v, txt[it], sizeof(struct ENTRY)); + } + + for (it = 0; it < countof(txt); it++) { + struct ENTRY *e = wget_vector_get(v, it); + if (!strcmp(e->txt,txt_sorted[it].txt)) + ok++; + else + failed++; + } + + wget_vector_free(&v); +} + +// this hash function generates collisions and reduces the map to a simple list. +// O(1) insertion, but O(n) search and removal +static unsigned int hash_txt(G_GNUC_WGET_UNUSED const char *key) +{ + return 0; +} + +static void test_stringmap(void) +{ + wget_stringmap_t *m; + char key[128], value[128], *val; + int run, it; + size_t valuesize; + + // the initial size of 16 forces the internal reshashing function to be called twice + + m = wget_stringmap_create(16); + + for (run = 0; run < 2; run++) { + if (run) { + wget_stringmap_clear(m); + wget_stringmap_sethashfunc(m, hash_txt); + } + + for (it = 0; it < 26; it++) { + sprintf(key, "http://www.example.com/subdir/%d.html", it); + valuesize = sprintf(value, "%d.html", it); + if (wget_stringmap_put(m, key, value, valuesize + 1)) { + failed++; + info_printf("stringmap_put(%s) returns unexpected old value\n", key); + } else ok++; + } + + if ((it = wget_stringmap_size(m)) != 26) { + failed++; + info_printf("stringmap_size() returned %d (expected %d)\n", it, 26); + } else ok++; + + // now, look up every single entry + for (it = 0; it < 26; it++) { + sprintf(key, "http://www.example.com/subdir/%d.html", it); + sprintf(value, "%d.html", it); + if (!(val = wget_stringmap_get(m, key))) { + failed++; + info_printf("stringmap_get(%s) didn't find entry\n", key); + } else if (strcmp(val, value)) { + failed++; + info_printf("stringmap_get(%s) found '%s' (expected '%s')\n", key, val, value); + } else ok++; + } + + wget_stringmap_clear(m); + + if ((it = wget_stringmap_size(m)) != 0) { + failed++; + info_printf("stringmap_size() returned %d (expected 0)\n", it); + } else ok++; + + for (it = 0; it < 26; it++) { + sprintf(key, "http://www.example.com/subdir/%d.html", it); + valuesize = sprintf(value, "%d.html", it); + if (wget_stringmap_put(m, key, value, valuesize + 1)) { + failed++; + info_printf("stringmap_put(%s) returns unexpected old value\n", key); + } else ok++; + } + + if ((it = wget_stringmap_size(m)) != 26) { + failed++; + info_printf("stringmap_size() returned %d (expected %d)\n", it, 26); + } else ok++; + + // now, remove every single entry + for (it = 0; it < 26; it++) { + sprintf(key, "http://www.example.com/subdir/%d.html", it); + sprintf(value, "%d.html", it); + wget_stringmap_remove(m, key); + } + + if ((it = wget_stringmap_size(m)) != 0) { + failed++; + info_printf("stringmap_size() returned %d (expected 0)\n", it); + } else ok++; + + for (it = 0; it < 26; it++) { + sprintf(key, "http://www.example.com/subdir/%d.html", it); + valuesize = sprintf(value, "%d.html", it); + if (wget_stringmap_put(m, key, value, valuesize + 1)) { + failed++; + info_printf("stringmap_put(%s) returns unexpected old value\n", key); + } else ok++; + } + + if ((it = wget_stringmap_size(m)) != 26) { + failed++; + info_printf("stringmap_size() returned %d (expected %d)\n", it, 26); + } else ok++; + } + + // testing alloc/free in stringmap/hashmap + wget_stringmap_clear(m); + wget_stringmap_put(m, "thekey", NULL, 0) ? failed++ : ok++; + wget_stringmap_put(m, "thekey", NULL, 0) ? ok++ : failed++; + wget_stringmap_put(m, "thekey", "thevalue", 9) ? ok++ : failed++; + wget_stringmap_put(m, "thekey", "thevalue", 9) ? ok++ : failed++; + wget_stringmap_put(m, "thekey", NULL, 0) ? ok++ : failed++; + + // testing key/value identity alloc/free in stringmap/hashmap + wget_stringmap_clear(m); + wget_stringmap_put(m, "thekey", NULL, 0) ? failed++ : ok++; + wget_stringmap_put(m, "thekey", NULL, 0) ? ok++ : failed++; + wget_stringmap_put(m, "thekey", "thevalue", 9) ? ok++ : failed++; + wget_stringmap_put(m, "thekey", NULL, 0) ? ok++ : failed++; + + wget_stringmap_free(&m); + + wget_http_challenge_t challenge; + wget_http_parse_challenge("Basic realm=\"test realm\"", &challenge); + wget_http_free_challenge(&challenge); + + wget_vector_t *challenges; + challenges = wget_vector_create(2, 2, NULL); + wget_vector_set_destructor(challenges, (void(*)(void *))wget_http_free_challenge); + wget_http_parse_challenge("Basic realm=\"test realm\"", &challenge); + wget_vector_add(challenges, &challenge, sizeof(challenge)); + wget_http_free_challenges(&challenges); + + char *response_text = strdup( +"HTTP/1.1 401 Authorization Required\r\n"\ +"Date: Sun, 23 Dec 2012 21:03:45 GMT\r\n"\ +"Server: Apache/2.2.22 (Debian)\r\n"\ +"WWW-Authenticate: Digest realm=\"therealm\", nonce=\"Ip6MaovRBAA=c4af733c51270698260f5d357724c2cbce20fa3d\", algorithm=MD5, domain=\"/prot_digest_md5\", qop=\"auth\"\r\n"\ +"Vary: Accept-Encoding\r\n"\ +"Content-Length: 476\r\n"\ +"Keep-Alive: timeout=5, max=99\r\n"\ +"Connection: Keep-Alive\r\n"\ +"Content-Type: text/html; charset=iso-8859-1\r\n\r\n"); + + wget_iri_t *iri = wget_iri_parse("http://localhost/prot_digest_md5/", NULL); + wget_http_request_t *req = wget_http_create_request(iri, "GET"); + wget_http_response_t *resp = wget_http_parse_response_header(response_text); + wget_http_add_credentials(req, wget_vector_get(resp->challenges, 0), "tim", "123"); +// for (it=0;it<vec_size(req->lines);it++) { +// info_printf("%s\n", (char *)vec_get(req->lines, it)); +// } + wget_http_free_response(&resp); + wget_http_free_request(&req); + wget_iri_free(&iri); + xfree(response_text); + +// Authorization: Digest username="tim", realm="therealm", nonce="Ip6MaovRBAA=c4af733c51270698260f5d357724c2cbce20fa3d", uri="/prot_digest_md5/", response="a99e2012d507a73dd46eb044d3f4641c", qop=auth, nc=00000001, cnonce="3d20faa1" + +} + +int main(int argc, const char * const *argv) +{ + // if VALGRIND testing is enabled, we have to call ourselves with valgrind checking + const char *valgrind = getenv("VALGRIND_TESTS"); + + if (!valgrind || !*valgrind || !strcmp(valgrind, "0")) { + // fallthrough + } + else if (!strcmp(valgrind, "1")) { + char cmd[strlen(argv[0]) + 256]; + + snprintf(cmd, sizeof(cmd), "VALGRIND_TESTS=\"\" valgrind --error-exitcode=301 --leak-check=yes --show-reachable=yes --track-origins=yes %s", argv[0]); + return system(cmd) != 0; + } else { + char cmd[strlen(valgrind) + strlen(argv[0]) + 32]; + + snprintf(cmd, sizeof(cmd), "VALGRIND_TESTS="" %s %s", valgrind, argv[0]); + return system(cmd) != 0; + } + + init(argc, argv); // allows us to test with options (e.g. with --debug) + + srand((unsigned int) time(NULL)); + + // testing basic library functionality + test_buffer(); + test_buffer_printf(); + test_utils(); + test_strcasecmp_ascii(); + test_vector(); + test_stringmap(); + + if (failed) { + info_printf("ERROR: %d out of %d basic tests failed\n", failed, ok + failed); + info_printf("This may completely break Wget functionality !!!\n"); + return 1; + } + + test_iri_parse(); + test_iri_relative_to_absolute(); + test_iri_compare(); + test_parser(); + + test_cookies(); + test_hsts(); + test_parse_challenge(); + + selftest_options() ? failed++ : ok++; + + deinit(); // free resources allocated by init() + + if (failed) { + info_printf("Summary: %d out of %d tests failed\n", failed, ok + failed); + return 1; + } + + info_printf("Summary: All %d tests passed\n", ok + failed); + return 0; +} |