├── .gitignore ├── .travis.yml ├── LICENSE ├── Makefile.am ├── README.md ├── configure.ac ├── duk_config.h ├── duktape.c ├── duktape.h ├── m4 └── .gitkeep ├── nsProxyAutoConfig.h ├── pac.c ├── pac.h ├── tests ├── 1.js ├── 2.js ├── 3.js ├── 4.js ├── 5.js ├── 6.js ├── Makefile.am ├── greatest.h ├── test1.sh ├── test2.sh ├── test3.sh ├── test4.sh ├── test5.sh ├── test6.sh ├── test7.sh ├── test_helper ├── test_helper.h ├── test_pac.c ├── test_unit1.c ├── test_unit2.c └── test_unit3.c ├── threadpool.c ├── threadpool.h ├── util.c └── util.h /.gitignore: -------------------------------------------------------------------------------- 1 | .*.d 2 | .*.dd 3 | *.a 4 | *.la 5 | *.lo 6 | *.oo 7 | *.so 8 | *.o 9 | *.pyc 10 | *.dll 11 | .deps 12 | .dirstamp 13 | .libs 14 | .*.swp 15 | 16 | Makefile 17 | Makefile.in 18 | cscope.out 19 | tags 20 | 21 | .clang_complete 22 | .ycm_extra_conf.py 23 | 24 | /aclocal.m4 25 | /autom4te*.cache 26 | /compile 27 | /confdefs.h 28 | /config.h* 29 | /config.log 30 | /config.status 31 | /config.guess 32 | /config.sub 33 | /configure 34 | /depcomp 35 | /install-sh 36 | /libtool 37 | /ltmain.sh 38 | /missing 39 | /stamp-h1 40 | /build-stamp 41 | /configure-stamp 42 | /config.guess.dh-orig 43 | /config.sub.dh-orig 44 | /m4/*.m4 45 | 46 | test_pac 47 | test_pac.exe 48 | 49 | /test-driver 50 | tests/test-suite.log 51 | tests/test*.log 52 | tests/test*.trs 53 | tests/test_unit* 54 | 55 | /build/ 56 | 57 | debian/*.debhelper.* 58 | 59 | !/tests/test_*.c 60 | !/tests/test_client 61 | !/m4/.gitkeep 62 | 63 | *~ 64 | *#*# 65 | .#* 66 | .DS_Store 67 | .vagrant 68 | Vagrantfile* 69 | core.[0-9]* 70 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: c 2 | compiler: gcc 3 | before_script: 4 | - sudo apt-get install gdb 5 | script: autoreconf -i && ./configure && make && make check 6 | after_failure: 7 | - cat config.log 8 | - cat tests/test-suite.log 9 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright 2014 Sauce Labs Inc. 2 | 3 | Licensed under the Apache License, Version 2.0 (the "License"); 4 | you may not use this file except in compliance with the License. 5 | You may obtain a copy of the License at 6 | 7 | http://www.apache.org/licenses/LICENSE-2.0 8 | 9 | Unless required by applicable law or agreed to in writing, software 10 | distributed under the License is distributed on an "AS IS" BASIS, 11 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | See the License for the specific language governing permissions and 13 | limitations under the License. 14 | -------------------------------------------------------------------------------- /Makefile.am: -------------------------------------------------------------------------------- 1 | ACLOCAL_AMFLAGS = -I m4 2 | 3 | AM_CPPFLAGS = -I$(top_builddir) -I$(top_srcdir) \ 4 | -I$(top_builddir)/include -I$(top_srcdir)/include \ 5 | @LOCAL_CPPFLAGS@ $(EXTRA_CPPFLAGS) 6 | AM_LDFLAGS = @LOCAL_LDFLAGS@ $(EXTRA_LDFLAGS) 7 | 8 | LIBS += $(EXTRA_LIBS) 9 | 10 | SUBDIRS = . tests 11 | 12 | include_HEADERS = pac.h 13 | 14 | pkgconfigdir=$(libdir)/pkgconfig 15 | 16 | LIBRARY_VERSION = 0:0:0 17 | 18 | SOURCES = duktape.c pac.c threadpool.c util.c 19 | 20 | lib_LTLIBRARIES = libpac.la 21 | libpac_la_SOURCES = $(SOURCES) 22 | libpac_la_LDFLAGS = -version-info $(LIBRARY_VERSION) 23 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Libpac 2 | ====== 3 | 4 | This is a C library for handling proxy autoconfiguration files. You can also use it to test your PAC files. 5 | 6 | Libpac is non-blocking and was created with non-blocking, event-based applications in mind. Since several PAC javascript functions might block, it uses a threadpool to execute your PAC javascript code. You supply a notification function to `pac_init`, and it will be called when a worker thread finished executing your PAC code. You can then schedule an event for your main event loop with the result. 7 | 8 | Build 9 | ----- 10 | 11 | You need `autoconf` and `automake`. For the first time, you need to generate `configure`: 12 | 13 | $ autoreconf -i 14 | 15 | Then build libpac: 16 | 17 | $ ./configure 18 | $ make 19 | 20 | To run tests: 21 | 22 | $ make check 23 | 24 | Note: with old versions, you needed `--enable-deep-c-stack` for the javascript engine be able to handle deeply recursive stacks (large PAC files with complex checks might require this). 25 | 26 | Example 27 | ------- 28 | 29 | See `tests/test_pac.c` for an example on how to use `libpac`. 30 | 31 | Testing your PAC file 32 | --------------------- 33 | 34 | You can use `tests/test_pac` to test your PAC file. It takes the path for your PAC file as its first parameter, then an URL and a hostname. E.g.: 35 | 36 | $ ./tests/test_pac ~/pac.js http://mysite.com mysite.com 37 | Found proxy PROXY 4.5.6.7:8080; PROXY 7.8.9.10:8080 38 | 39 | PAC files can return one or more proxies, or "DIRECT" for a direct connection. 40 | 41 | You can also call `test_pac` with multiple URL/hostname pairs: 42 | 43 | $ ./tests/test_pac ~/pac.js http://mysite.com mysite.com http://mysite.net mysite.net 44 | Found proxy PROXY 4.5.6.7:8080 45 | Found proxy PROXY 7.8.9.10:8080 46 | -------------------------------------------------------------------------------- /configure.ac: -------------------------------------------------------------------------------- 1 | # -*- Autoconf -*- 2 | # Process this file with autoconf to produce a configure script. 3 | 4 | AC_INIT([libpac], [0.0.0], [v.nebehaj@gmail.com]) 5 | AC_CONFIG_SRCDIR([pac.c]) 6 | AC_CONFIG_HEADERS([config.h]) 7 | AC_CONFIG_MACRO_DIR([m4]) 8 | 9 | PKG_PROG_PKG_CONFIG 10 | 11 | AM_INIT_AUTOMAKE([foreign subdir-objects]) 12 | 13 | LT_INIT 14 | 15 | # Checks for programs. 16 | AC_PROG_CC 17 | AC_PROG_LIBTOOL 18 | 19 | AC_MSG_CHECKING(for WIN32) 20 | AC_TRY_COMPILE(, 21 | [ 22 | #ifndef WIN32 23 | die horribly 24 | #endif 25 | ], 26 | bwin32=true; AC_MSG_RESULT(yes), 27 | bwin32=false; AC_MSG_RESULT(no), 28 | ) 29 | AM_CONDITIONAL(BUILD_WIN32, test x$bwin32 = xtrue) 30 | 31 | AC_ARG_ENABLE([deep-c-stack], 32 | [ --enable-deep-c-stack build with deep C stack enabled], 33 | [deep_c_stack=true], [deep_c_stack=false]) 34 | 35 | LOCAL_CPPFLAGS="-std=c99 -pedantic -Wall -O2 -g" 36 | if test x$deep_c_stack = xtrue; then 37 | LOCAL_CPPFLAGS="$LOCAL_CPPFLAGS" 38 | fi 39 | LOCAL_LDFLAGS="" 40 | if test "$bwin32" = true; then 41 | LOCAL_CPPFLAGS="$LOCAL_CPPFLAGS -mno-ms-bitfields -D_WIN32_WINNT=0x0600" 42 | else 43 | LOCAL_CPPFLAGS="$LOCAL_CPPFLAGS -D_GNU_SOURCE -D_POSIX_C_SOURCE -D_DARWIN_C_SOURCE -D_XOPEN_SOURCE" 44 | LOCAL_LDFLAGS="$LOCAL_LDFLAGS -rdynamic" 45 | fi 46 | 47 | # -lm 48 | AC_SEARCH_LIBS([cos], [m], [], [AC_MSG_ERROR([not found])]) 49 | 50 | # -lpthread 51 | AC_SEARCH_LIBS([pthread_create], [pthread], [], [AC_MSG_ERROR([not found])]) 52 | AC_CHECK_HEADER([pthread.h], [], [AC_MSG_ERROR([not found])]) 53 | 54 | if test "$bwin32" = true; then 55 | AC_CHECK_LIB(iphlpapi, main) 56 | AC_CHECK_LIB(kernel32, main) 57 | AC_CHECK_LIB(ws2_32, main) 58 | AC_CHECK_LIB(gdi32, main) 59 | AC_CHECK_LIB(dbghelp, main) 60 | fi 61 | 62 | AC_SUBST(LOCAL_CPPFLAGS) 63 | AC_SUBST(LOCAL_LDFLAGS) 64 | 65 | AC_CONFIG_FILES([Makefile tests/Makefile]) 66 | AC_OUTPUT 67 | -------------------------------------------------------------------------------- /m4/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ldx/libpac/b1eedd6670e10f93c6640d1700ef69703a20caef/m4/.gitkeep -------------------------------------------------------------------------------- /nsProxyAutoConfig.h: -------------------------------------------------------------------------------- 1 | /* 2 | * This is based on nsProxyAutoConfig.js from Mozilla. 3 | */ 4 | static const char *nsProxyAutoConfig = 5 | "function dnsDomainIs(host, domain) {\n" 6 | " return (host.length >= domain.length &&\n" 7 | " host.substring(host.length - domain.length) == domain);\n" 8 | "}\n" 9 | 10 | "function dnsDomainLevels(host) {\n" 11 | " return host.split('.').length-1;\n" 12 | "}\n" 13 | 14 | "function convert_addr(ipchars) {\n" 15 | " var bytes = ipchars.split('.');\n" 16 | " var result = ((bytes[0] & 0xff) << 24) |\n" 17 | " ((bytes[1] & 0xff) << 16) |\n" 18 | " ((bytes[2] & 0xff) << 8) |\n" 19 | " (bytes[3] & 0xff);\n" 20 | " return result;\n" 21 | "}\n" 22 | 23 | "function isInNet(ipaddr, pattern, maskstr) {\n" 24 | " var re = /^(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})$/;" 25 | " var test = re.exec(ipaddr);" 26 | " if (test == null) {\n" 27 | " ipaddr = dnsResolve(ipaddr);\n" 28 | " if (ipaddr == null)\n" 29 | " return false;\n" 30 | " } else if (test[1] > 255 || test[2] > 255 || \n" 31 | " test[3] > 255 || test[4] > 255) {\n" 32 | " return false; // not an IP address\n" 33 | " }\n" 34 | " var host = convert_addr(ipaddr);\n" 35 | " var pat = convert_addr(pattern);\n" 36 | " var mask = convert_addr(maskstr);\n" 37 | " return ((host & mask) == (pat & mask));\n" 38 | " \n" 39 | "}\n" 40 | 41 | "function isPlainHostName(host) {\n" 42 | " return (host.search('\\\\.') == -1);\n" 43 | "}\n" 44 | 45 | "function isResolvable(host) {\n" 46 | " var ip = dnsResolve(host);\n" 47 | " return (ip != null);\n" 48 | "}\n" 49 | 50 | "function localHostOrDomainIs(host, hostdom) {\n" 51 | " return (host == hostdom) ||\n" 52 | " (hostdom.lastIndexOf(host + '.', 0) == 0);\n" 53 | "}\n" 54 | 55 | "function shExpMatch(url, pattern) {\n" 56 | " pattern = pattern.replace(/\\./g, '\\\\.');\n" 57 | " pattern = pattern.replace(/\\*/g, '.*');\n" 58 | " pattern = pattern.replace(/\\?/g, '.');\n" 59 | " var newRe = new RegExp('^'+pattern+'$');\n" 60 | " return newRe.test(url);\n" 61 | "}\n" 62 | 63 | "var wdays = {SUN: 0, MON: 1, TUE: 2, WED: 3, THU: 4, FRI: 5, SAT: 6};\n" 64 | 65 | "function weekdayRange() {\n" 66 | " function getDay(weekday) {\n" 67 | " if (weekday in wdays) {\n" 68 | " return wdays[weekday];\n" 69 | " }\n" 70 | " return -1;\n" 71 | " }\n" 72 | " var date = new Date();\n" 73 | " var argc = arguments.length;\n" 74 | " var wday;\n" 75 | " if (argc < 1)\n" 76 | " return false;\n" 77 | " if (arguments[argc - 1] == 'GMT') {\n" 78 | " argc--;\n" 79 | " wday = date.getUTCDay();\n" 80 | " } else {\n" 81 | " wday = date.getDay();\n" 82 | " }\n" 83 | " var wd1 = getDay(arguments[0]);\n" 84 | " var wd2 = (argc == 2) ? getDay(arguments[1]) : wd1;\n" 85 | " return (wd1 == -1 || wd2 == -1) ? false\n" 86 | " : (wd1 <= wday && wday <= wd2);\n" 87 | "}\n"; 88 | 89 | static const char *nsProxyAutoConfig0 = 90 | "var months = {JAN: 0, FEB: 1, MAR: 2, APR: 3, MAY: 4, JUN: 5, JUL: 6, AUG: 7, SEP: 8, OCT: 9, NOV: 10, DEC: 11};\n" 91 | 92 | "function dateRange() {\n" 93 | " function getMonth(name) {\n" 94 | " if (name in months) {\n" 95 | " return months[name];\n" 96 | " }\n" 97 | " return -1;\n" 98 | " }\n" 99 | " var date = new Date();\n" 100 | " var argc = arguments.length;\n" 101 | " if (argc < 1) {\n" 102 | " return false;\n" 103 | " }\n" 104 | " var isGMT = (arguments[argc - 1] == 'GMT');\n" 105 | "\n" 106 | " if (isGMT) {\n" 107 | " argc--;\n" 108 | " }\n" 109 | " // function will work even without explict handling of this case\n" 110 | " if (argc == 1) {\n" 111 | " var tmp = parseInt(arguments[0]);\n" 112 | " if (isNaN(tmp)) {\n" 113 | " return ((isGMT ? date.getUTCMonth() : date.getMonth()) ==\n" 114 | "getMonth(arguments[0]));\n" 115 | " } else if (tmp < 32) {\n" 116 | " return ((isGMT ? date.getUTCDate() : date.getDate()) == tmp);\n" 117 | " } else { \n" 118 | " return ((isGMT ? date.getUTCFullYear() : date.getFullYear()) ==\n" 119 | "tmp);\n" 120 | " }\n" 121 | " }\n" 122 | " var year = date.getFullYear();\n" 123 | " var date1, date2;\n" 124 | " date1 = new Date(year, 0, 1, 0, 0, 0);\n" 125 | " date2 = new Date(year, 11, 31, 23, 59, 59);\n" 126 | " var adjustMonth = false;\n" 127 | " for (var i = 0; i < (argc >> 1); i++) {\n" 128 | " var tmp = parseInt(arguments[i]);\n" 129 | " if (isNaN(tmp)) {\n" 130 | " var mon = getMonth(arguments[i]);\n" 131 | " date1.setMonth(mon);\n" 132 | " } else if (tmp < 32) {\n" 133 | " adjustMonth = (argc <= 2);\n" 134 | " date1.setDate(tmp);\n" 135 | " } else {\n" 136 | " date1.setFullYear(tmp);\n" 137 | " }\n" 138 | " }\n" 139 | " for (var i = (argc >> 1); i < argc; i++) {\n" 140 | " var tmp = parseInt(arguments[i]);\n" 141 | " if (isNaN(tmp)) {\n" 142 | " var mon = getMonth(arguments[i]);\n" 143 | " date2.setMonth(mon);\n" 144 | " } else if (tmp < 32) {\n" 145 | " date2.setDate(tmp);\n" 146 | " } else {\n" 147 | " date2.setFullYear(tmp);\n" 148 | " }\n" 149 | " }\n" 150 | " if (adjustMonth) {\n" 151 | " date1.setMonth(date.getMonth());\n" 152 | " date2.setMonth(date.getMonth());\n" 153 | " }\n" 154 | " if (isGMT) {\n" 155 | " var tmp = date;\n" 156 | " tmp.setFullYear(date.getUTCFullYear());\n" 157 | " tmp.setMonth(date.getUTCMonth());\n" 158 | " tmp.setDate(date.getUTCDate());\n" 159 | " tmp.setHours(date.getUTCHours());\n" 160 | " tmp.setMinutes(date.getUTCMinutes());\n" 161 | " tmp.setSeconds(date.getUTCSeconds());\n" 162 | " date = tmp;\n" 163 | " }\n" 164 | " return ((date1 <= date) && (date <= date2));\n" 165 | "}\n" 166 | 167 | "function timeRange() {\n" 168 | " var argc = arguments.length;\n" 169 | " var date = new Date();\n" 170 | " var isGMT= false;\n" 171 | "\n" 172 | " if (argc < 1) {\n" 173 | " return false;\n" 174 | " }\n" 175 | " if (arguments[argc - 1] == 'GMT') {\n" 176 | " isGMT = true;\n" 177 | " argc--;\n" 178 | " }\n" 179 | "\n" 180 | " var hour = isGMT ? date.getUTCHours() : date.getHours();\n" 181 | " var date1, date2;\n" 182 | " date1 = new Date();\n" 183 | " date2 = new Date();\n" 184 | "\n" 185 | " if (argc == 1) {\n" 186 | " return (hour == arguments[0]);\n" 187 | " } else if (argc == 2) {\n" 188 | " return ((arguments[0] <= hour) && (hour <= arguments[1]));\n" 189 | " } else {\n" 190 | " switch (argc) {\n" 191 | " case 6:\n" 192 | " date1.setSeconds(arguments[2]);\n" 193 | " date2.setSeconds(arguments[5]);\n" 194 | " case 4:\n" 195 | " var middle = argc >> 1;\n" 196 | " date1.setHours(arguments[0]);\n" 197 | " date1.setMinutes(arguments[1]);\n" 198 | " date2.setHours(arguments[middle]);\n" 199 | " date2.setMinutes(arguments[middle + 1]);\n" 200 | " if (middle == 2) {\n" 201 | " date2.setSeconds(59);\n" 202 | " }\n" 203 | " break;\n" 204 | " default:\n" 205 | " throw 'timeRange: bad number of arguments'\n" 206 | " }\n" 207 | " }\n" 208 | "\n" 209 | " if (isGMT) {\n" 210 | " date.setFullYear(date.getUTCFullYear());\n" 211 | " date.setMonth(date.getUTCMonth());\n" 212 | " date.setDate(date.getUTCDate());\n" 213 | " date.setHours(date.getUTCHours());\n" 214 | " date.setMinutes(date.getUTCMinutes());\n" 215 | " date.setSeconds(date.getUTCSeconds());\n" 216 | " }\n" 217 | " return ((date1 <= date) && (date <= date2));\n" 218 | "}\n"; 219 | 220 | -------------------------------------------------------------------------------- /pac.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #if defined(_WIN32) || defined(__CYGWIN__) 8 | #include 9 | #else 10 | #include 11 | #include 12 | #endif 13 | 14 | #include "duktape.h" 15 | #include "threadpool.h" 16 | 17 | #include "nsProxyAutoConfig.h" 18 | #include "util.h" 19 | 20 | #include "pac.h" 21 | 22 | /* 23 | * There are external PAC functions with multiple versions: a "plain" one, 24 | * returning only one result (e.g. dnsResolve() only returning one IP 25 | * address, such as "1.2.3.4"), and an *_ex version, returning optionally 26 | * multiple results, concanated via a ';', such as "1.2.3.4;5.6.7.8". 27 | */ 28 | #define RETURN_SINGLE_RESULT 0 29 | #define RETURN_ALL_RESULTS 1 30 | 31 | struct pac { 32 | char *javascript; /* JavaScript PAC code. */ 33 | threadpool_t *threadpool; 34 | pthread_mutex_t ctx_mtx; 35 | int n_ctx; 36 | duk_context **ctx; 37 | }; 38 | 39 | struct proxy_args { 40 | struct pac *pac; 41 | char *url; 42 | char *host; 43 | void (*cb)(char *, void *); 44 | char *result; 45 | void *arg; 46 | }; 47 | 48 | /* 49 | * Pluggable logger function. The user can override the default one via 50 | * pac_set_log_fn(). 51 | */ 52 | static void default_log_fn(int level, const char *buf) 53 | { 54 | if (level == PAC_LOGLVL_WARN) 55 | fprintf(stderr, "[PAC] %s\n", buf); 56 | } 57 | 58 | static log_fn_type log_fn = default_log_fn; 59 | 60 | void pac_set_log_fn(log_fn_type fn) 61 | { 62 | log_fn = fn; 63 | } 64 | 65 | #ifdef __GNUC__ 66 | #define LOG_ATTR __attribute__((format(printf, 2, 3))) 67 | #else 68 | #define LOG_ATTR 69 | #endif 70 | 71 | static void _pac_log(int level, const char *fmt, ...) LOG_ATTR; 72 | 73 | static void _pac_log(int level, const char *fmt, ...) 74 | { 75 | va_list args; 76 | char buf[1024]; 77 | 78 | if (!log_fn) 79 | return; 80 | 81 | va_start(args,fmt); 82 | vsnprintf(buf, sizeof(buf), fmt, args); 83 | va_end(args); 84 | 85 | log_fn(level, buf); 86 | } 87 | 88 | #define logw(...) do { \ 89 | _pac_log(PAC_LOGLVL_WARN, __VA_ARGS__); \ 90 | } while(0) 91 | #define logi(fmt, ...) do { \ 92 | _pac_log(PAC_LOGLVL_INFO, __VA_ARGS__); \ 93 | } while(0) 94 | #define logd(fmt, ...) do { \ 95 | _pac_log(PAC_LOGLVL_DEBUG, __VA_ARGS__); \ 96 | } while(0) 97 | 98 | static void fatal_handler(void *udata, const char *msg) 99 | { 100 | logw("Fatal error: %s (%p).", msg, udata); 101 | } 102 | 103 | /* 104 | * Note: error handling in these function is not standardized. The best 105 | * documentation available is: 106 | * 107 | * https://msdn.microsoft.com/en-us/library/windows/desktop/gg308477(v=vs.85).aspx 108 | * 109 | * which states that (at least for the *Ex versions) the function should 110 | * return an empty string if an error occurs (and not throw an error). 111 | */ 112 | static int _dns_resolve(duk_context *ctx, int all_results) 113 | { 114 | char buf[UTIL_BUFLEN]; 115 | const char *host = duk_require_string(ctx, 0); 116 | 117 | if (util_dns_resolve(host, buf, sizeof(buf), all_results) < 0) 118 | buf[0] = '\0'; 119 | 120 | duk_push_string(ctx, buf); 121 | return 1; 122 | } 123 | 124 | static int dns_resolve(duk_context *ctx) 125 | { 126 | return _dns_resolve(ctx, RETURN_SINGLE_RESULT); 127 | } 128 | 129 | static int dns_resolve_ex(duk_context *ctx) 130 | { 131 | return _dns_resolve(ctx, RETURN_ALL_RESULTS); 132 | } 133 | 134 | static int _my_ip_address(duk_context *ctx, int all_results) 135 | { 136 | char buf[UTIL_BUFLEN]; 137 | 138 | if (util_my_ip_address(buf, sizeof(buf), all_results) < 0) 139 | buf[0] = '\0'; 140 | 141 | duk_push_string(ctx, buf); 142 | return 1; 143 | } 144 | 145 | static int my_ip_address(duk_context *ctx) 146 | { 147 | return _my_ip_address(ctx, RETURN_SINGLE_RESULT); 148 | } 149 | 150 | static int my_ip_address_ex(duk_context *ctx) 151 | { 152 | return _my_ip_address(ctx, RETURN_ALL_RESULTS); 153 | } 154 | 155 | static void *alloc_ctx(char *js) 156 | { 157 | duk_context *ctx; 158 | 159 | ctx = duk_create_heap(NULL, NULL, NULL, NULL, fatal_handler); 160 | if (!ctx) 161 | return ctx; 162 | 163 | duk_push_global_object(ctx); 164 | duk_push_c_function(ctx, dns_resolve, 1 /*nargs*/); 165 | duk_put_prop_string(ctx, -2, "dnsResolve"); 166 | duk_push_c_function(ctx, my_ip_address, 0 /*nargs*/); 167 | duk_put_prop_string(ctx, -2, "myIpAddress"); 168 | duk_push_c_function(ctx, dns_resolve_ex, 1 /*nargs*/); 169 | duk_put_prop_string(ctx, -2, "dnsResolveEx"); 170 | duk_push_c_function(ctx, my_ip_address_ex, 0 /*nargs*/); 171 | duk_put_prop_string(ctx, -2, "myIpAddressEx"); 172 | duk_pop(ctx); 173 | 174 | duk_eval_string(ctx, nsProxyAutoConfig); 175 | duk_pop(ctx); 176 | 177 | duk_eval_string(ctx, nsProxyAutoConfig0); 178 | duk_pop(ctx); 179 | 180 | /* Try to evaluate our Javascript PAC file. */ 181 | if (duk_peval_string(ctx, js) != 0) { 182 | logw("Failed to evaluate PAC file: %s.", duk_safe_to_string(ctx, -1)); 183 | duk_pop(ctx); 184 | duk_destroy_heap(ctx); 185 | errno = EINVAL; 186 | return NULL; 187 | } 188 | duk_pop(ctx); 189 | 190 | return ctx; 191 | } 192 | 193 | static char *find_proxy(duk_context *ctx, char *url, char *host) 194 | { 195 | char *result = NULL; 196 | const char *proxy; 197 | 198 | duk_push_global_object(ctx); 199 | duk_get_prop_string(ctx, -1 /*index*/, "FindProxyForURL"); 200 | duk_push_string(ctx, url); 201 | duk_push_string(ctx, host); 202 | 203 | if (duk_pcall(ctx, 2 /*nargs*/) == DUK_EXEC_SUCCESS) { 204 | proxy = duk_to_string(ctx, -1); 205 | if (!proxy) 206 | logw("Failed to allocate proxy string."); 207 | else 208 | result = strdup(proxy); 209 | } else { 210 | if (duk_is_error(ctx, -1)) { 211 | /* 212 | * Accessing .stack might cause an error to be thrown, so 213 | * wrap this access in a duk_safe_call() if it matters. 214 | */ 215 | duk_get_prop_string(ctx, -1, "stack"); 216 | logw("Javascript call failed: %s.", duk_safe_to_string(ctx, -1)); 217 | duk_pop(ctx); /* Result string. */ 218 | } else { 219 | /* Non-Error value, coerce safely to string. */ 220 | logw("Javascript call failed: %s.", duk_safe_to_string(ctx, -1)); 221 | } 222 | } 223 | 224 | duk_pop(ctx); /* Result string. */ 225 | duk_pop(ctx); /* Global object. */ 226 | 227 | return result; 228 | } 229 | 230 | static void main_result(void *arg) 231 | { 232 | struct proxy_args *pa = arg; 233 | 234 | if (pa->host != NULL) { 235 | logw("Assertion error: pa->host == %p", pa->host); 236 | } 237 | if (pa->url != NULL) { 238 | logw("Assertion error: pa->url == %p", pa->url); 239 | } 240 | 241 | pa->cb(pa->result, pa->arg); 242 | 243 | free(pa); 244 | } 245 | 246 | static duk_context *pop_context(struct pac *pac) 247 | { 248 | int i; 249 | 250 | pthread_mutex_lock(&pac->ctx_mtx); 251 | 252 | for (i = 0; i < pac->n_ctx; i++) { 253 | if (pac->ctx[i] != NULL) { 254 | duk_context *ctx = pac->ctx[i]; 255 | pac->ctx[i] = NULL; 256 | pthread_mutex_unlock(&pac->ctx_mtx); 257 | return ctx; 258 | } 259 | } 260 | 261 | pthread_mutex_unlock(&pac->ctx_mtx); 262 | 263 | assert(0); 264 | } 265 | 266 | static void push_context(struct pac *pac, duk_context *ctx) 267 | { 268 | int i; 269 | 270 | pthread_mutex_lock(&pac->ctx_mtx); 271 | 272 | for (i = 0; i < pac->n_ctx; i++) { 273 | if (pac->ctx[i] == NULL) { 274 | pac->ctx[i] = ctx; 275 | pthread_mutex_unlock(&pac->ctx_mtx); 276 | return; 277 | } 278 | } 279 | 280 | pthread_mutex_unlock(&pac->ctx_mtx); 281 | 282 | assert(0); 283 | } 284 | 285 | static void _pac_find_proxy(void *arg) 286 | { 287 | struct proxy_args *pa = arg; 288 | struct pac *pac = pa->pac; 289 | duk_context *ctx = pop_context(pac); 290 | 291 | pa->result = find_proxy(ctx, pa->url, pa->host); 292 | 293 | free(pa->host); 294 | pa->host = NULL; 295 | free(pa->url); 296 | pa->url = NULL; 297 | 298 | push_context(pac, ctx); 299 | 300 | threadpool_schedule_back(pac->threadpool, main_result, pa); 301 | } 302 | 303 | int pac_find_proxy(struct pac *pac, char *url, char *host, 304 | void (*cb)(char *_result, void *_arg), void *arg) 305 | { 306 | struct proxy_args *pa = malloc(sizeof(struct proxy_args)); 307 | 308 | if (!pa) { 309 | logw("Failed to allocate proxy arguments."); 310 | return -1; 311 | } 312 | 313 | pa->pac = pac; 314 | pa->url = strdup(url); 315 | pa->host = strdup(host); 316 | pa->arg = arg; 317 | pa->cb = cb; 318 | pa->result = NULL; 319 | 320 | if (!pa->url || !pa->host) { 321 | logw("Failed to allocate proxy arguments."); 322 | return -1; 323 | } 324 | 325 | if (threadpool_schedule(pac->threadpool, _pac_find_proxy, pa) < 0) { 326 | logw("Failed to schedule work item."); 327 | return -1; 328 | } 329 | 330 | return 0; 331 | } 332 | 333 | int pac_find_proxy_sync(char *js, char *url, char *host, char **proxy) 334 | { 335 | duk_context *ctx = alloc_ctx(js); 336 | if (ctx) { 337 | *proxy = find_proxy(ctx, url, host); 338 | duk_destroy_heap(ctx); 339 | return 0; 340 | } else { 341 | logw("Failed to allocate JS context."); 342 | return -1; 343 | } 344 | } 345 | 346 | void pac_run_callbacks(struct pac *pac) 347 | { 348 | threadpool_run_callbacks(pac->threadpool); 349 | } 350 | 351 | static int check_js(char *js) 352 | { 353 | duk_context *ctx = alloc_ctx(js); 354 | if (!ctx) 355 | return -1; 356 | 357 | duk_destroy_heap(ctx); 358 | 359 | return 0; 360 | } 361 | 362 | struct pac *pac_init(char *js, int n_threads, void (*notify_cb)(void *), 363 | void *arg) 364 | { 365 | struct pac *pac = NULL; 366 | int i, ret = check_js(js); 367 | if (ret) 368 | goto err; 369 | 370 | ret = -1; 371 | 372 | pac = calloc(1, sizeof(struct pac)); 373 | if (!pac) { 374 | logw("Error allocating PAC."); 375 | goto err; 376 | } 377 | 378 | pac->javascript = strdup(js); 379 | pac->n_ctx = n_threads; /* One context per worker thread. */ 380 | pac->ctx = calloc(pac->n_ctx, sizeof(duk_context *)); 381 | pac->threadpool = threadpool_create(n_threads, notify_cb, arg); 382 | if (!pac->javascript || !pac->ctx || !pac->threadpool) { 383 | logw("Error setting up PAC."); 384 | goto err; 385 | } 386 | 387 | for (i = 0; i < pac->n_ctx; i++) { 388 | pac->ctx[i] = alloc_ctx(js); 389 | if (!pac->ctx[i]) { 390 | logw("Error creating PAC context #%d.", i); 391 | goto err; 392 | } 393 | } 394 | 395 | if (pthread_mutex_init(&pac->ctx_mtx, NULL)) { 396 | logw("Error initializing mutex."); 397 | goto err; 398 | } 399 | 400 | return pac; 401 | 402 | err: 403 | if (pac && pac->javascript) 404 | free(pac->javascript); 405 | if (pac && pac->ctx) { 406 | for (i = 0; i < n_threads; i++) 407 | if (pac->ctx[i]) 408 | duk_destroy_heap(pac->ctx[i]); 409 | free(pac->ctx); 410 | } 411 | if (pac && pac->threadpool) 412 | threadpool_die(pac->threadpool, 1); 413 | if (pac) 414 | free(pac); 415 | return NULL; 416 | } 417 | 418 | void pac_free(struct pac *pac) 419 | { 420 | free(pac->javascript); 421 | duk_destroy_heap(*pac->ctx); 422 | threadpool_die(pac->threadpool, 1); 423 | free(pac); 424 | } 425 | -------------------------------------------------------------------------------- /pac.h: -------------------------------------------------------------------------------- 1 | struct pac; 2 | 3 | struct pac *pac_init(char *js, int n_threads, void (*notify_cb)(void *), 4 | void *arg); 5 | int pac_find_proxy(struct pac *pac, char *url, char *host, 6 | void (*cb)(char *_result, void *_arg), void *arg); 7 | int pac_find_proxy_sync(char *js, char *url, char *host, char **proxy); 8 | void pac_run_callbacks(struct pac *pac); 9 | 10 | #define PAC_LOGLVL_DEBUG 0x00 11 | #define PAC_LOGLVL_INFO 0x01 12 | #define PAC_LOGLVL_WARN 0x02 13 | 14 | typedef void (*log_fn_type)(int, const char *); 15 | void pac_set_log_fn(log_fn_type fn); 16 | -------------------------------------------------------------------------------- /tests/1.js: -------------------------------------------------------------------------------- 1 | function FindProxyForURL(url, host) { 2 | 3 | // If the hostname matches, send direct. 4 | if (dnsDomainIs(host, ".intranet.domain.com") || 5 | shExpMatch(host, "(*.abcdomain.com|abcdomain.com)")) 6 | return "DIRECT"; 7 | 8 | // If the protocol or URL matches, send direct. 9 | if (url.substring(0, 4)=="ftp:" || 10 | shExpMatch(url, "http://abcdomain.com/folder/*")) 11 | return "DIRECT"; 12 | 13 | // If the requested website is hosted within the internal network, send direct. 14 | if (isPlainHostName(host) || 15 | shExpMatch(host, "*.local") || 16 | isInNet(dnsResolve(host), "10.0.0.0", "255.0.0.0") || 17 | isInNet(dnsResolve(host), "172.16.0.0", "255.240.0.0") || 18 | isInNet(dnsResolve(host), "192.168.0.0", "255.255.0.0") || 19 | isInNet(dnsResolve(host), "127.0.0.0", "255.255.255.0")) 20 | return "DIRECT"; 21 | 22 | // If the IP address of the local machine is within a defined 23 | // subnet, send to a specific proxy. 24 | if (isInNet(myIpAddress(), "10.10.5.0", "255.255.255.0")) 25 | return "PROXY 1.2.3.4:8080"; 26 | 27 | // DEFAULT RULE: All other traffic, use below proxies, in fail-over order. 28 | return "PROXY 4.5.6.7:8080; PROXY 7.8.9.10:8080"; 29 | 30 | } 31 | -------------------------------------------------------------------------------- /tests/2.js: -------------------------------------------------------------------------------- 1 | // This PAC file is from http://cns.ntou.edu.tw/lib.pac. 2 | 3 | function FindProxyForURL(url, host) { 4 | var RESOLV_IP; 5 | var lchost = host.toLowerCase(); 6 | if(check(host,"*.*.ebscohost.com",false,true)) 7 | return "PROXY proxylib.ntou.edu.tw:3128"; 8 | if(check(host,"*.ebsco-content.com",false,true)) 9 | return "PROXY proxylib.ntou.edu.tw:3128"; 10 | if(check(host,"129.35.213.31",false,true)) 11 | return "PROXY proxylib.ntou.edu.tw:3128"; 12 | if(check(host,"129.35.248.48",false,true)) 13 | return "PROXY proxylib.ntou.edu.tw:3128"; 14 | if(check(host,"134.243.85.3",false,true)) 15 | return "PROXY proxylib.ntou.edu.tw:3128"; 16 | if(check(host,"134.243.85.4",false,true)) 17 | return "PROXY proxylib.ntou.edu.tw:3128"; 18 | if(check(host,"140.121.140.100",false,true)) 19 | return "PROXY proxylib.ntou.edu.tw:3128"; 20 | if(check(host,"140.121.140.102",false,true)) 21 | return "PROXY proxylib.ntou.edu.tw:3128"; 22 | if(check(host,"140.121.140.103",false,true)) 23 | return "PROXY proxylib.ntou.edu.tw:3128"; 24 | if(check(host,"140.121.180.109",false,true)) 25 | return "PROXY proxylib.ntou.edu.tw:3128"; 26 | if(check(host,"156.csis.com.tw",false,true)) 27 | return "PROXY proxylib.ntou.edu.tw:3128"; 28 | if(check(host,"165.193.122.",false,true)) 29 | return "PROXY proxylib.ntou.edu.tw:3128"; 30 | if(check(host,"165.193.141.",false,true)) 31 | return "PROXY proxylib.ntou.edu.tw:3128"; 32 | if(check(host,"167.216.170.",false,true)) 33 | return "PROXY proxylib.ntou.edu.tw:3128"; 34 | if(check(host,"167.216.171.",false,true)) 35 | return "PROXY proxylib.ntou.edu.tw:3128"; 36 | if(check(host,"170.225.184.106",false,true)) 37 | return "PROXY proxylib.ntou.edu.tw:3128"; 38 | if(check(host,"170.225.184.107",false,true)) 39 | return "PROXY proxylib.ntou.edu.tw:3128"; 40 | if(check(host,"170.225.96.21",false,true)) 41 | return "PROXY proxylib.ntou.edu.tw:3128"; 42 | if(check(host,"170.225.99.9",false,true)) 43 | return "PROXY proxylib.ntou.edu.tw:3128"; 44 | if(check(host,"192.83.186.103",false,true)) 45 | return "PROXY proxylib.ntou.edu.tw:3128"; 46 | if(check(host,"192.83.186.70",false,true)) 47 | return "PROXY proxylib.ntou.edu.tw:3128"; 48 | if(check(host,"192.83.186.71",false,true)) 49 | return "PROXY proxylib.ntou.edu.tw:3128"; 50 | if(check(host,"192.83.186.72",false,true)) 51 | return "PROXY proxylib.ntou.edu.tw:3128"; 52 | if(check(host,"192.83.186.84",false,true)) 53 | return "PROXY proxylib.ntou.edu.tw:3128"; 54 | if(check(host,"199.4.154.",false,true)) 55 | return "PROXY proxylib.ntou.edu.tw:3128"; 56 | if(check(host,"199.4.155.",false,true)) 57 | return "PROXY proxylib.ntou.edu.tw:3128"; 58 | if(check(host,"202.70.173.2",false,true)) 59 | return "PROXY proxylib.ntou.edu.tw:3128"; 60 | if(check(host,"203.70.208.88",false,true)) 61 | return "PROXY proxylib.ntou.edu.tw:3128"; 62 | if(check(host,"203.74.36.75",false,true)) 63 | return "PROXY proxylib.ntou.edu.tw:3128"; 64 | if(check(host,"205.240.244.",false,true)) 65 | return "PROXY proxylib.ntou.edu.tw:3128"; 66 | if(check(host,"205.240.245.",false,true)) 67 | return "PROXY proxylib.ntou.edu.tw:3128"; 68 | if(check(host,"205.240.246.",false,true)) 69 | return "PROXY proxylib.ntou.edu.tw:3128"; 70 | if(check(host,"205.240.247.",false,true)) 71 | return "PROXY proxylib.ntou.edu.tw:3128"; 72 | if(check(host,"205.243.231.",false,true)) 73 | return "PROXY proxylib.ntou.edu.tw:3128"; 74 | if(check(host,"210.243.166.93",false,true)) 75 | return "PROXY proxylib.ntou.edu.tw:3128"; 76 | if(check(host,"211.20.182.42",false,true)) 77 | return "PROXY proxylib.ntou.edu.tw:3128"; 78 | if(check(host,"211.79.206.2",false,true)) 79 | return "PROXY proxylib.ntou.edu.tw:3128"; 80 | if(check(host,"211.79.206.4",false,true)) 81 | return "PROXY proxylib.ntou.edu.tw:3128"; 82 | if(check(host,"211.79.506.4",false,true)) 83 | return "PROXY proxylib.ntou.edu.tw:3128"; 84 | if(check(host,"220.228.59.156",false,true)) 85 | return "PROXY proxylib.ntou.edu.tw:3128"; 86 | if(check(host,"63.240.105.",false,true)) 87 | return "PROXY proxylib.ntou.edu.tw:3128"; 88 | if(check(host,"63.240.113.",false,true)) 89 | return "PROXY proxylib.ntou.edu.tw:3128"; 90 | if(check(host,"63.84.162.",false,true)) 91 | return "PROXY proxylib.ntou.edu.tw:3128"; 92 | if(check(host,"63.86.118.",false,true)) 93 | return "PROXY proxylib.ntou.edu.tw:3128"; 94 | if(check(host,"63.86.119.",false,true)) 95 | return "PROXY proxylib.ntou.edu.tw:3128"; 96 | if(check(host,"65.246.184.",false,true)) 97 | return "PROXY proxylib.ntou.edu.tw:3128"; 98 | if(check(host,"65.246.185.",false,true)) 99 | return "PROXY proxylib.ntou.edu.tw:3128"; 100 | if(check(host,"aac.asm.org",false,true)) 101 | return "PROXY proxylib.ntou.edu.tw:3128"; 102 | if(check(host,"ac.els-cdn.com",false,true)) 103 | return "PROXY proxylib.ntou.edu.tw:3128"; 104 | if(check(host,"admin-apps.webofknowledge.com",false,true)) 105 | return "PROXY proxylib.ntou.edu.tw:3128"; 106 | if(check(host,"admin-router.webofknowledge.com",false,true)) 107 | return "PROXY proxylib.ntou.edu.tw:3128"; 108 | if(check(host,"admin.webofknowledge.com",false,true)) 109 | return "PROXY proxylib.ntou.edu.tw:3128"; 110 | if(check(host,"aem.asm.org",false,true)) 111 | return "PROXY proxylib.ntou.edu.tw:3128"; 112 | if(check(host,"afraf.oupjournals.org",false,true)) 113 | return "PROXY proxylib.ntou.edu.tw:3128"; 114 | if(check(host,"ageing.oupjournals.org",false,true)) 115 | return "PROXY proxylib.ntou.edu.tw:3128"; 116 | if(check(host,"aje.oupjournals.org",false,true)) 117 | return "PROXY proxylib.ntou.edu.tw:3128"; 118 | if(check(host,"alcalc.oupjournals.org",false,true)) 119 | return "PROXY proxylib.ntou.edu.tw:3128"; 120 | if(check(host,"aler.oupjournals.org",false,true)) 121 | return "PROXY proxylib.ntou.edu.tw:3128"; 122 | if(check(host,"annhyg.oupjournals.org",false,true)) 123 | return "PROXY proxylib.ntou.edu.tw:3128"; 124 | if(check(host,"annonc.oupjournals.org",false,true)) 125 | return "PROXY proxylib.ntou.edu.tw:3128"; 126 | if(check(host,"antonio.ingentaselect.com",false,true)) 127 | return "PROXY proxylib.ntou.edu.tw:3128"; 128 | if(check(host,"ao.osa.org",false,true)) 129 | return "PROXY proxylib.ntou.edu.tw:3128"; 130 | if(check(host,"aob.oupjournals.org",false,true)) 131 | return "PROXY proxylib.ntou.edu.tw:3128"; 132 | if(check(host,"aoip.osa.org",false,true)) 133 | return "PROXY proxylib.ntou.edu.tw:3128"; 134 | if(check(host,"aolp.osa.org",false,true)) 135 | return "PROXY proxylib.ntou.edu.tw:3128"; 136 | if(check(host,"aoot.osa.org",false,true)) 137 | return "PROXY proxylib.ntou.edu.tw:3128"; 138 | if(check(host,"ap.ejournal.ascc.net",false,true)) 139 | return "PROXY proxylib.ntou.edu.tw:3128"; 140 | if(check(host,"apl.aip.org",false,true)) 141 | return "PROXY proxylib.ntou.edu.tw:3128"; 142 | if(check(host,"apollo.sinica.edu.tw",false,true)) 143 | return "PROXY proxylib.ntou.edu.tw:3128"; 144 | if(check(host,"apps.webofknowledge.com",false,true)) 145 | return "PROXY proxylib.ntou.edu.tw:3128"; 146 | if(check(host,"apps.webofknowledgev4.com",false,true)) 147 | return "PROXY proxylib.ntou.edu.tw:3128"; 148 | if(check(host,"arjournals.annualreviews.org",false,true)) 149 | return "PROXY proxylib.ntou.edu.tw:3128"; 150 | if(check(host,"ascelibrary.aip.org",false,true)) 151 | return "PROXY proxylib.ntou.edu.tw:3128"; 152 | if(check(host,"atoz.ebsco.com",false,true)) 153 | return "PROXY proxylib.ntou.edu.tw:3128"; 154 | if(check(host,"beck-online.beck.de",false,true)) 155 | return "PROXY proxylib.ntou.edu.tw:3128"; 156 | if(check(host,"beheco.oupjournals.org",false,true)) 157 | return "PROXY proxylib.ntou.edu.tw:3128"; 158 | if(check(host,"bencao.infolinker.com.tw",false,true)) 159 | return "PROXY proxylib.ntou.edu.tw:3128"; 160 | if(check(host,"big5.oversea.cnki.net",false,true)) 161 | return "PROXY proxylib.ntou.edu.tw:3128"; 162 | if(check(host,"bioinformatics.oupjournals.org",false,true)) 163 | return "PROXY proxylib.ntou.edu.tw:3128"; 164 | if(check(host,"biostatistics.oupjournals.org",false,true)) 165 | return "PROXY proxylib.ntou.edu.tw:3128"; 166 | if(check(host,"bizboard.nikkeibp.co.jp",false,true)) 167 | return "PROXY proxylib.ntou.edu.tw:3128"; 168 | if(check(host,"bizboard.nikkeibp.co.jp/daigaku",false,true)) 169 | return "PROXY proxylib.ntou.edu.tw:3128"; 170 | if(check(host,"bja.oupjournals.org",false,true)) 171 | return "PROXY proxylib.ntou.edu.tw:3128"; 172 | if(check(host,"bjc.oupjournals.org",false,true)) 173 | return "PROXY proxylib.ntou.edu.tw:3128"; 174 | if(check(host,"bjsw.oupjournals.org",false,true)) 175 | return "PROXY proxylib.ntou.edu.tw:3128"; 176 | if(check(host,"bmb.oupjournals.org",false,true)) 177 | return "PROXY proxylib.ntou.edu.tw:3128"; 178 | if(check(host,"bmf.aip.org",false,true)) 179 | return "PROXY proxylib.ntou.edu.tw:3128"; 180 | if(check(host,"brain.oupjournals.org",false,true)) 181 | return "PROXY proxylib.ntou.edu.tw:3128"; 182 | if(check(host,"brief-treatment.oupjournals.org",false,true)) 183 | return "PROXY proxylib.ntou.edu.tw:3128"; 184 | if(check(host,"carcin.oupjournals.org",false,true)) 185 | return "PROXY proxylib.ntou.edu.tw:3128"; 186 | if(check(host,"cco.cambridge.org",false,true)) 187 | return "PROXY proxylib.ntou.edu.tw:3128"; 188 | if(check(host,"cdj.oupjournals.org",false,true)) 189 | return "PROXY proxylib.ntou.edu.tw:3128"; 190 | if(check(host,"cdli.asm.org",false,true)) 191 | return "PROXY proxylib.ntou.edu.tw:3128"; 192 | if(check(host,"cds1.webofknowledge.com",false,true)) 193 | return "PROXY proxylib.ntou.edu.tw:3128"; 194 | if(check(host,"cds2.webofknowledge.com",false,true)) 195 | return "PROXY proxylib.ntou.edu.tw:3128"; 196 | if(check(host,"cec.lib.apabi.com",false,true)) 197 | return "PROXY proxylib.ntou.edu.tw:3128"; 198 | if(check(host,"cep.oupjournals.org",false,true)) 199 | return "PROXY proxylib.ntou.edu.tw:3128"; 200 | if(check(host,"cercor.oupjournals.org",false,true)) 201 | return "PROXY proxylib.ntou.edu.tw:3128"; 202 | if(check(host,"chaos.aip.org",false,true)) 203 | return "PROXY proxylib.ntou.edu.tw:3128"; 204 | if(check(host,"charts.webofknowledge.com",false,true)) 205 | return "PROXY proxylib.ntou.edu.tw:3128"; 206 | if(check(host,"chemse.oupjournals.org",false,true)) 207 | return "PROXY proxylib.ntou.edu.tw:3128"; 208 | if(check(host,"ci.nii.ac.jp",false,true)) 209 | return "PROXY proxylib.ntou.edu.tw:3128"; 210 | if(check(host,"cje.oupjournals.org",false,true)) 211 | return "PROXY proxylib.ntou.edu.tw:3128"; 212 | if(check(host,"cjn.csis.com.tw",false,true)) 213 | return "PROXY proxylib.ntou.edu.tw:3128"; 214 | if(check(host,"clipsy.oupjournals.org",false,true)) 215 | return "PROXY proxylib.ntou.edu.tw:3128"; 216 | if(check(host,"cm.webofknowledge.com",false,true)) 217 | return "PROXY proxylib.ntou.edu.tw:3128"; 218 | if(check(host,"cm.webofknowledgev4.com",false,true)) 219 | return "PROXY proxylib.ntou.edu.tw:3128"; 220 | if(check(host,"cmr.asm.org",false,true)) 221 | return "PROXY proxylib.ntou.edu.tw:3128"; 222 | if(check(host,"cnki.csis.com.tw",false,true)) 223 | return "PROXY proxylib.ntou.edu.tw:3128"; 224 | if(check(host,"cnki50.csis.com.tw",false,true)) 225 | return "PROXY proxylib.ntou.edu.tw:3128"; 226 | if(check(host,"collections.chadwyck.co.uk",false,true)) 227 | return "PROXY proxylib.ntou.edu.tw:3128"; 228 | if(check(host,"concert.wisenews.net.tw",false,true)) 229 | return "PROXY proxylib.ntou.edu.tw:3128"; 230 | if(check(host,"content.ebscohost.com",false,true)) 231 | return "PROXY proxylib.ntou.edu.tw:3128"; 232 | if(check(host,"cornell.mirror.aps.org",false,true)) 233 | return "PROXY proxylib.ntou.edu.tw:3128"; 234 | if(check(host,"cpe.oupjournals.org",false,true)) 235 | return "PROXY proxylib.ntou.edu.tw:3128"; 236 | if(check(host,"csa.e-lib.nctu.edu.tw",false,true)) 237 | return "PROXY proxylib.ntou.edu.tw:3128"; 238 | if(check(host,"ct.oupjournals.org",false,true)) 239 | return "PROXY proxylib.ntou.edu.tw:3128"; 240 | if(check(host,"database.yomiuri.co.jp",false,true)) 241 | return "PROXY proxylib.ntou.edu.tw:3128"; 242 | if(check(host,"db.lib.ntou.edu.tw",false,true)) 243 | return "PROXY proxylib.ntou.edu.tw:3128"; 244 | if(check(host,"deafed.oupjournals.org",false,true)) 245 | return "PROXY proxylib.ntou.edu.tw:3128"; 246 | if(check(host,"delivery.acm.org",false,true)) 247 | return "PROXY proxylib.ntou.edu.tw:3128"; 248 | if(check(host,"demomars.csis.com.tw",false,true)) 249 | return "PROXY proxylib.ntou.edu.tw:3128"; 250 | if(check(host,"diipcs.webofknowledge.com",false,true)) 251 | return "PROXY proxylib.ntou.edu.tw:3128"; 252 | if(check(host,"dlib.apabi.com",false,true)) 253 | return "PROXY proxylib.ntou.edu.tw:3128"; 254 | if(check(host,"download.springer.com",false,true)) 255 | return "PROXY proxylib.ntou.edu.tw:3128"; 256 | if(check(host,"ea.grolier.com",false,true)) 257 | return "PROXY proxylib.ntou.edu.tw:3128"; 258 | if(check(host,"earthinteractions.org",false,true)) 259 | return "PROXY proxylib.ntou.edu.tw:3128"; 260 | if(check(host,"ebook01.koobe.com.tw",false,true)) 261 | return "PROXY proxylib.ntou.edu.tw:3128"; 262 | if(check(host,"ebooks.abc-clio.com",false,true)) 263 | return "PROXY proxylib.ntou.edu.tw:3128"; 264 | if(check(host,"ebooks.kluweronline.com",false,true)) 265 | return "PROXY proxylib.ntou.edu.tw:3128"; 266 | if(check(host,"ebooks.springerlink.com",false,true)) 267 | return "PROXY proxylib.ntou.edu.tw:3128"; 268 | if(check(host,"ebooks.windeal.com.tw",false,true)) 269 | return "PROXY proxylib.ntou.edu.tw:3128"; 270 | if(check(host,"ec.asm.org",false,true)) 271 | return "PROXY proxylib.ntou.edu.tw:3128"; 272 | if(check(host,"edo.tw",false,true)) 273 | return "PROXY proxylib.ntou.edu.tw:3128"; 274 | if(check(host,"edo.tw/ocp.aspx?subs_no=20063",false,true)) 275 | return "PROXY proxylib.ntou.edu.tw:3128"; 276 | if(check(host,"eds.a.ebscohost.com",false,true)) 277 | return "PROXY proxylib.ntou.edu.tw:3128"; 278 | if(check(host,"eds.b.ebscohost.com",false,true)) 279 | return "PROXY proxylib.ntou.edu.tw:3128"; 280 | if(check(host,"eds.c.ebscohost.com",false,true)) 281 | return "PROXY proxylib.ntou.edu.tw:3128"; 282 | if(check(host,"eds.d.ebscohost.com",false,true)) 283 | return "PROXY proxylib.ntou.edu.tw:3128"; 284 | if(check(host,"eds.e.ebscohost.com",false,true)) 285 | return "PROXY proxylib.ntou.edu.tw:3128"; 286 | if(check(host,"edu1.wordpedia.com",false,true)) 287 | return "PROXY proxylib.ntou.edu.tw:3128"; 288 | if(check(host,"eebo.chadwyck.com",false,true)) 289 | return "PROXY proxylib.ntou.edu.tw:3128"; 290 | if(check(host,"ei.e-lib.nctu.edu.tw",false,true)) 291 | return "PROXY proxylib.ntou.edu.tw:3128"; 292 | if(check(host,"ei.oupjournals.org",false,true)) 293 | return "PROXY proxylib.ntou.edu.tw:3128"; 294 | if(check(host,"ei.stic.gov.tw",false,true)) 295 | return "PROXY proxylib.ntou.edu.tw:3128"; 296 | if(check(host,"ej.iop.org",false,true)) 297 | return "PROXY proxylib.ntou.edu.tw:3128"; 298 | if(check(host,"elearning.webenglish.tv",false,true)) 299 | return "PROXY proxylib.ntou.edu.tw:3128"; 300 | if(check(host,"elib.infolinker.com.tw",false,true)) 301 | return "PROXY proxylib.ntou.edu.tw:3128"; 302 | if(check(host,"emboj.oupjournals.org",false,true)) 303 | return "PROXY proxylib.ntou.edu.tw:3128"; 304 | if(check(host,"engineer.windeal.com.tw",false,true)) 305 | return "PROXY proxylib.ntou.edu.tw:3128"; 306 | if(check(host,"enterprise.astm.org",false,true)) 307 | return "PROXY proxylib.ntou.edu.tw:3128"; 308 | if(check(host,"epirev.oupjournals.org",false,true)) 309 | return "PROXY proxylib.ntou.edu.tw:3128"; 310 | if(check(host,"epubs.siam.org",false,true)) 311 | return "PROXY proxylib.ntou.edu.tw:3128"; 312 | if(check(host,"erae.oupjournals.org",false,true)) 313 | return "PROXY proxylib.ntou.edu.tw:3128"; 314 | if(check(host,"eric.lib.nccu.edu.tw",false,true)) 315 | return "PROXY proxylib.ntou.edu.tw:3128"; 316 | if(check(host,"es.oupjournals.org",false,true)) 317 | return "PROXY proxylib.ntou.edu.tw:3128"; 318 | if(check(host,"esi.webofknowledge.com",false,true)) 319 | return "PROXY proxylib.ntou.edu.tw:3128"; 320 | if(check(host,"esr.oupjournals.org",false,true)) 321 | return "PROXY proxylib.ntou.edu.tw:3128"; 322 | if(check(host,"estipub.isiknowledge.com",false,true)) 323 | return "PROXY proxylib.ntou.edu.tw:3128"; 324 | if(check(host,"ethesys.lib.ntou.edu.tw",false,true)) 325 | return "PROXY proxylib.ntou.edu.tw:3128"; 326 | if(check(host,"fampra.oupjournals.org",false,true)) 327 | return "PROXY proxylib.ntou.edu.tw:3128"; 328 | if(check(host,"g.wanfangdata.com.hk",false,true)) 329 | return "PROXY proxylib.ntou.edu.tw:3128"; 330 | if(check(host,"galenet.galegroup.com",false,true)) 331 | return "PROXY proxylib.ntou.edu.tw:3128"; 332 | if(check(host,"gateway.webofknowledge.com",false,true)) 333 | return "PROXY proxylib.ntou.edu.tw:3128"; 334 | if(check(host,"german2.nccu.edu.tw",false,true)) 335 | return "PROXY proxylib.ntou.edu.tw:3128"; 336 | if(check(host,"global.ebsco-content.com",false,true)) 337 | return "PROXY proxylib.ntou.edu.tw:3128"; 338 | if(check(host,"global.umi.com",false,true)) 339 | return "PROXY proxylib.ntou.edu.tw:3128"; 340 | if(check(host,"globalbb.onesource.com",false,true)) 341 | return "PROXY proxylib.ntou.edu.tw:3128"; 342 | if(check(host,"glycob.oupjournals.org",false,true)) 343 | return "PROXY proxylib.ntou.edu.tw:3128"; 344 | if(check(host,"gme.grolier.com",false,true)) 345 | return "PROXY proxylib.ntou.edu.tw:3128"; 346 | if(check(host,"go-passport.grolier.com",false,true)) 347 | return "PROXY proxylib.ntou.edu.tw:3128"; 348 | if(check(host,"go.galegroup.com",false,true)) 349 | return "PROXY proxylib.ntou.edu.tw:3128"; 350 | if(check(host,"go.grolier.com",false,true)) 351 | return "PROXY proxylib.ntou.edu.tw:3128"; 352 | if(check(host,"go.westlawjapan.com",false,true)) 353 | return "PROXY proxylib.ntou.edu.tw:3128"; 354 | if(check(host,"haworthpress.com",false,true)) 355 | return "PROXY proxylib.ntou.edu.tw:3128"; 356 | if(check(host,"hbrtwn.infolinker.com.tw",false,true)) 357 | return "PROXY proxylib.ntou.edu.tw:3128"; 358 | if(check(host,"hcr.oupjournals.org",false,true)) 359 | return "PROXY proxylib.ntou.edu.tw:3128"; 360 | if(check(host,"hcr3.webofknowledge.com",false,true)) 361 | return "PROXY proxylib.ntou.edu.tw:3128"; 362 | if(check(host,"heapol.oupjournals.org",false,true)) 363 | return "PROXY proxylib.ntou.edu.tw:3128"; 364 | if(check(host,"heapro.oupjournals.org",false,true)) 365 | return "PROXY proxylib.ntou.edu.tw:3128"; 366 | if(check(host,"her.oupjournals.org",false,true)) 367 | return "PROXY proxylib.ntou.edu.tw:3128"; 368 | if(check(host,"hjournals.cambridge.org",false,true)) 369 | return "PROXY proxylib.ntou.edu.tw:3128"; 370 | if(check(host,"hk.wanfangdata.com",false,true)) 371 | return "PROXY proxylib.ntou.edu.tw:3128"; 372 | if(check(host,"hmg.oupjournals.org",false,true)) 373 | return "PROXY proxylib.ntou.edu.tw:3128"; 374 | if(check(host,"http://infotrac.galegroup.com",false,true)) 375 | return "PROXY proxylib.ntou.edu.tw:3128"; 376 | if(check(host,"humrep.oupjournals.org",false,true)) 377 | return "PROXY proxylib.ntou.edu.tw:3128"; 378 | if(check(host,"hunteq.com",false,true)) 379 | return "PROXY proxylib.ntou.edu.tw:3128"; 380 | if(check(host,"huso.stpi.narl.org.tw",false,true)) 381 | return "PROXY proxylib.ntou.edu.tw:3128"; 382 | if(check(host,"huso.stpi.org.tw",false,true)) 383 | return "PROXY proxylib.ntou.edu.tw:3128"; 384 | if(check(host,"hyweb.ebook.hyread.com.tw",false,true)) 385 | return "PROXY proxylib.ntou.edu.tw:3128"; 386 | if(check(host,"iai.asm.org",false,true)) 387 | return "PROXY proxylib.ntou.edu.tw:3128"; 388 | if(check(host,"icc.oupjournals.org",false,true)) 389 | return "PROXY proxylib.ntou.edu.tw:3128"; 390 | if(check(host,"ieee.org",false,true)) 391 | return "PROXY proxylib.ntou.edu.tw:3128"; 392 | if(check(host,"igroup.ebrary.com",false,true)) 393 | return "PROXY proxylib.ntou.edu.tw:3128"; 394 | if(check(host,"ije.oupjournals.org",false,true)) 395 | return "PROXY proxylib.ntou.edu.tw:3128"; 396 | if(check(host,"ijpor.oupjournals.org",false,true)) 397 | return "PROXY proxylib.ntou.edu.tw:3128"; 398 | if(check(host,"ilibrary.com.tw",false,true)) 399 | return "PROXY proxylib.ntou.edu.tw:3128"; 400 | if(check(host,"imagebank.osa.org",false,true)) 401 | return "PROXY proxylib.ntou.edu.tw:3128"; 402 | if(check(host,"images.webofknowledge.com",false,true)) 403 | return "PROXY proxylib.ntou.edu.tw:3128"; 404 | if(check(host,"infotrac.galegroup.com",false,true)) 405 | return "PROXY proxylib.ntou.edu.tw:3128"; 406 | if(check(host,"infoweb.newsbank.com",false,true)) 407 | return "PROXY proxylib.ntou.edu.tw:3128"; 408 | if(check(host,"international.westlaw.com",false,true)) 409 | return "PROXY proxylib.ntou.edu.tw:3128"; 410 | if(check(host,"intimm.oupjournals.org",false,true)) 411 | return "PROXY proxylib.ntou.edu.tw:3128"; 412 | if(check(host,"intqhc.oupjournals.org",false,true)) 413 | return "PROXY proxylib.ntou.edu.tw:3128"; 414 | if(check(host,"iopscience.iop.org",false,true)) 415 | return "PROXY proxylib.ntou.edu.tw:3128"; 416 | if(check(host,"iospress.metapress.com",false,true)) 417 | return "PROXY proxylib.ntou.edu.tw:3128"; 418 | if(check(host,"irap.oupjournals.org",false,true)) 419 | return "PROXY proxylib.ntou.edu.tw:3128"; 420 | if(check(host,"isi4.isiknowledge.com",false,true)) 421 | return "PROXY proxylib.ntou.edu.tw:3128"; 422 | if(check(host,"isiknowledge.com",false,true)) 423 | return "PROXY proxylib.ntou.edu.tw:3128"; 424 | if(check(host,"jac.oupjournals.org",false,true)) 425 | return "PROXY proxylib.ntou.edu.tw:3128"; 426 | if(check(host,"jae.oupjournals.org",false,true)) 427 | return "PROXY proxylib.ntou.edu.tw:3128"; 428 | if(check(host,"jap.aip.org",false,true)) 429 | return "PROXY proxylib.ntou.edu.tw:3128"; 430 | if(check(host,"jb.asm.org",false,true)) 431 | return "PROXY proxylib.ntou.edu.tw:3128"; 432 | if(check(host,"jcm.asm.org",false,true)) 433 | return "PROXY proxylib.ntou.edu.tw:3128"; 434 | if(check(host,"jcp.aip.org",false,true)) 435 | return "PROXY proxylib.ntou.edu.tw:3128"; 436 | if(check(host,"jcr1.isiknowledge.com",false,true)) 437 | return "PROXY proxylib.ntou.edu.tw:3128"; 438 | if(check(host,"jeg.oupjournals.org",false,true)) 439 | return "PROXY proxylib.ntou.edu.tw:3128"; 440 | if(check(host,"jhered.oupjournals.org",false,true)) 441 | return "PROXY proxylib.ntou.edu.tw:3128"; 442 | if(check(host,"jjco.oupjournals.org",false,true)) 443 | return "PROXY proxylib.ntou.edu.tw:3128"; 444 | if(check(host,"jleo.oupjournals.org",false,true)) 445 | return "PROXY proxylib.ntou.edu.tw:3128"; 446 | if(check(host,"jlt.osa.org",false,true)) 447 | return "PROXY proxylib.ntou.edu.tw:3128"; 448 | if(check(host,"jmicro.oupjournals.org",false,true)) 449 | return "PROXY proxylib.ntou.edu.tw:3128"; 450 | if(check(host,"jmp.aip.org",false,true)) 451 | return "PROXY proxylib.ntou.edu.tw:3128"; 452 | if(check(host,"jn.physiology.org",false,true)) 453 | return "PROXY proxylib.ntou.edu.tw:3128"; 454 | if(check(host,"jncicancerspectrum.oupjournals.org",false,true)) 455 | return "PROXY proxylib.ntou.edu.tw:3128"; 456 | if(check(host,"joc.oupjournals.org",false,true)) 457 | return "PROXY proxylib.ntou.edu.tw:3128"; 458 | if(check(host,"josaa.osa.org",false,true)) 459 | return "PROXY proxylib.ntou.edu.tw:3128"; 460 | if(check(host,"jot.osa.org",false,true)) 461 | return "PROXY proxylib.ntou.edu.tw:3128"; 462 | if(check(host,"journals.ametsoc.org",false,true)) 463 | return "PROXY proxylib.ntou.edu.tw:3128"; 464 | if(check(host,"journals.asm.org",false,true)) 465 | return "PROXY proxylib.ntou.edu.tw:3128"; 466 | if(check(host,"journals.cambridge.org",false,true)) 467 | return "PROXY proxylib.ntou.edu.tw:3128"; 468 | if(check(host,"journals.kluweronline.com",false,true)) 469 | return "PROXY proxylib.ntou.edu.tw:3128"; 470 | if(check(host,"journals.wspc.com.sg",false,true)) 471 | return "PROXY proxylib.ntou.edu.tw:3128"; 472 | if(check(host,"jpart.oupjournals.org",false,true)) 473 | return "PROXY proxylib.ntou.edu.tw:3128"; 474 | if(check(host,"jpcrd.aip.org",false,true)) 475 | return "PROXY proxylib.ntou.edu.tw:3128"; 476 | if(check(host,"jpepsy.oupjournals.org",false,true)) 477 | return "PROXY proxylib.ntou.edu.tw:3128"; 478 | if(check(host,"jrse.aip.org",false,true)) 479 | return "PROXY proxylib.ntou.edu.tw:3128"; 480 | if(check(host,"jurban.oupjournals.org",false,true)) 481 | return "PROXY proxylib.ntou.edu.tw:3128"; 482 | if(check(host,"jvi.asm.org",false,true)) 483 | return "PROXY proxylib.ntou.edu.tw:3128"; 484 | if(check(host,"jxb.oupjournals.org",false,true)) 485 | return "PROXY proxylib.ntou.edu.tw:3128"; 486 | if(check(host,"klassiker.chadwyck.co.uk",false,true)) 487 | return "PROXY proxylib.ntou.edu.tw:3128"; 488 | if(check(host,"kmw.ctgin.com",false,true)) 489 | return "PROXY proxylib.ntou.edu.tw:3128"; 490 | if(check(host,"lang.ntou.edu.tw/source.php",false,true)) 491 | return "PROXY proxylib.ntou.edu.tw:3128"; 492 | if(check(host,"lb20.ah100.libraryandbook.net",false,true)) 493 | return "PROXY proxylib.ntou.edu.tw:3128"; 494 | if(check(host,"lb20.botw.libraryandbook.net",false,true)) 495 | return "PROXY proxylib.ntou.edu.tw:3128"; 496 | if(check(host,"lb20.dummies.libraryandbook.net",false,true)) 497 | return "PROXY proxylib.ntou.edu.tw:3128"; 498 | if(check(host,"lb20.tabf.libraryandbook.net",false,true)) 499 | return "PROXY proxylib.ntou.edu.tw:3128"; 500 | if(check(host,"legal.lexisnexis.jp",false,true)) 501 | return "PROXY proxylib.ntou.edu.tw:3128"; 502 | if(check(host,"lib.myilibrary.com",false,true)) 503 | return "PROXY proxylib.ntou.edu.tw:3128"; 504 | if(check(host,"library.books24x7.com",false,true)) 505 | return "PROXY proxylib.ntou.edu.tw:3128"; 506 | if(check(host,"library.pressdisplay.com",false,true)) 507 | return "PROXY proxylib.ntou.edu.tw:3128"; 508 | if(check(host,"link.aps.org",false,true)) 509 | return "PROXY proxylib.ntou.edu.tw:3128"; 510 | if(check(host,"link.springer-ny.com",false,true)) 511 | return "PROXY proxylib.ntou.edu.tw:3128"; 512 | if(check(host,"link.springer.com",false,true)) 513 | return "PROXY proxylib.ntou.edu.tw:3128"; 514 | if(check(host,"link.springer.de",false,true)) 515 | return "PROXY proxylib.ntou.edu.tw:3128"; 516 | if(check(host,"links.springer.com",false,true)) 517 | return "PROXY proxylib.ntou.edu.tw:3128"; 518 | if(check(host,"links.webofknowledge.com",false,true)) 519 | return "PROXY proxylib.ntou.edu.tw:3128"; 520 | if(check(host,"ltp.aip.org",false,true)) 521 | return "PROXY proxylib.ntou.edu.tw:3128"; 522 | if(check(host,"mars.csa.com",false,true)) 523 | return "PROXY proxylib.ntou.edu.tw:3128"; 524 | if(check(host,"mars.csis.com.tw",false,true)) 525 | return "PROXY proxylib.ntou.edu.tw:3128"; 526 | if(check(host,"mars2.csa.com",false,true)) 527 | return "PROXY proxylib.ntou.edu.tw:3128"; 528 | if(check(host,"mars3.csa.com",false,true)) 529 | return "PROXY proxylib.ntou.edu.tw:3128"; 530 | if(check(host,"mbe.oupjournals.org",false,true)) 531 | return "PROXY proxylib.ntou.edu.tw:3128"; 532 | if(check(host,"mcb.asm.org",false,true)) 533 | return "PROXY proxylib.ntou.edu.tw:3128"; 534 | if(check(host,"md1.csa.com",false,true)) 535 | return "PROXY proxylib.ntou.edu.tw:3128"; 536 | if(check(host,"md2.csa.com",false,true)) 537 | return "PROXY proxylib.ntou.edu.tw:3128"; 538 | if(check(host,"minghouse.infolinker.com.tw",false,true)) 539 | return "PROXY proxylib.ntou.edu.tw:3128"; 540 | if(check(host,"mmbr.asm.org",false,true)) 541 | return "PROXY proxylib.ntou.edu.tw:3128"; 542 | if(check(host,"molehr.oupjournals.org",false,true)) 543 | return "PROXY proxylib.ntou.edu.tw:3128"; 544 | if(check(host,"mollus.oupjournals.org",false,true)) 545 | return "PROXY proxylib.ntou.edu.tw:3128"; 546 | if(check(host,"mutage.oupjournals.org",false,true)) 547 | return "PROXY proxylib.ntou.edu.tw:3128"; 548 | if(check(host,"mydigitallibrary.lib.overdrive.com",false,true)) 549 | return "PROXY proxylib.ntou.edu.tw:3128"; 550 | if(check(host,"nar.oupjournals.org",false,true)) 551 | return "PROXY proxylib.ntou.edu.tw:3128"; 552 | if(check(host,"ncl3web.hyweb.com.tw",false,true)) 553 | return "PROXY proxylib.ntou.edu.tw:3128"; 554 | if(check(host,"ndt.oupjournals.org",false,true)) 555 | return "PROXY proxylib.ntou.edu.tw:3128"; 556 | if(check(host,"new.cwk.com.tw",false,true)) 557 | return "PROXY proxylib.ntou.edu.tw:3128"; 558 | if(check(host,"newfirstsearch.global.oclc.org",false,true)) 559 | return "PROXY proxylib.ntou.edu.tw:3128"; 560 | if(check(host,"newfirstsearch.oclc.org",false,true)) 561 | return "PROXY proxylib.ntou.edu.tw:3128"; 562 | if(check(host,"ntou.ebook.hyread.com.tw",false,true)) 563 | return "PROXY proxylib.ntou.edu.tw:3128"; 564 | if(check(host,"ntou.koobe.com.tw",false,true)) 565 | return "PROXY proxylib.ntou.edu.tw:3128"; 566 | if(check(host,"ntt1.hyweb.com.tw",false,true)) 567 | return "PROXY proxylib.ntou.edu.tw:3128"; 568 | if(check(host,"occmed.oupjournals.org",false,true)) 569 | return "PROXY proxylib.ntou.edu.tw:3128"; 570 | if(check(host,"oep.oupjournals.org",false,true)) 571 | return "PROXY proxylib.ntou.edu.tw:3128"; 572 | if(check(host,"oh1.csa.com",false,true)) 573 | return "PROXY proxylib.ntou.edu.tw:3128"; 574 | if(check(host,"oh2.csa.com",false,true)) 575 | return "PROXY proxylib.ntou.edu.tw:3128"; 576 | if(check(host,"ojps.aip.org",false,true)) 577 | return "PROXY proxylib.ntou.edu.tw:3128"; 578 | if(check(host,"ol.osa.org",false,true)) 579 | return "PROXY proxylib.ntou.edu.tw:3128"; 580 | if(check(host,"oldweb.cqvip.com",false,true)) 581 | return "PROXY proxylib.ntou.edu.tw:3128"; 582 | if(check(host,"omed.nuazure.info",false,true)) 583 | return "PROXY proxylib.ntou.edu.tw:3128"; 584 | if(check(host,"online.sagepub.com",false,true)) 585 | return "PROXY proxylib.ntou.edu.tw:3128"; 586 | if(check(host,"onlinelibrary.wiley.com",false,true)) 587 | return "PROXY proxylib.ntou.edu.tw:3128"; 588 | if(check(host,"ortho.oupjournals.org",false,true)) 589 | return "PROXY proxylib.ntou.edu.tw:3128"; 590 | if(check(host,"oversea.cnki.net",false,true)) 591 | return "PROXY proxylib.ntou.edu.tw:3128"; 592 | if(check(host,"ovid.stic.gov.tw",false,true)) 593 | return "PROXY proxylib.ntou.edu.tw:3128"; 594 | if(check(host,"ovidsp.ovid.com",false,true)) 595 | return "PROXY proxylib.ntou.edu.tw:3128"; 596 | if(check(host,"oxfordjournals.org",false,true)) 597 | return "PROXY proxylib.ntou.edu.tw:3128"; 598 | if(check(host,"oxrep.oupjournals.org",false,true)) 599 | return "PROXY proxylib.ntou.edu.tw:3128"; 600 | if(check(host,"pa.oupjournals.org",false,true)) 601 | return "PROXY proxylib.ntou.edu.tw:3128"; 602 | if(check(host,"pan.oupjournals.org",false,true)) 603 | return "PROXY proxylib.ntou.edu.tw:3128"; 604 | if(check(host,"pao.chadwyck.co.uk",false,true)) 605 | return "PROXY proxylib.ntou.edu.tw:3128"; 606 | if(check(host,"pcp.oupjournals.org",false,true)) 607 | return "PROXY proxylib.ntou.edu.tw:3128"; 608 | if(check(host,"pcs.webofknowledge.com",false,true)) 609 | return "PROXY proxylib.ntou.edu.tw:3128"; 610 | if(check(host,"pcs.webofknowledgev4com",false,true)) 611 | return "PROXY proxylib.ntou.edu.tw:3128"; 612 | if(check(host,"pdn.sciencedirect.com",false,true)) 613 | return "PROXY proxylib.ntou.edu.tw:3128"; 614 | if(check(host,"petrology.oupjournals.org",false,true)) 615 | return "PROXY proxylib.ntou.edu.tw:3128"; 616 | if(check(host,"phr.oupjournals.org",false,true)) 617 | return "PROXY proxylib.ntou.edu.tw:3128"; 618 | if(check(host,"physics.aps.org",false,true)) 619 | return "PROXY proxylib.ntou.edu.tw:3128"; 620 | if(check(host,"physiolgenomics.physiology.org",false,true)) 621 | return "PROXY proxylib.ntou.edu.tw:3128"; 622 | if(check(host,"plankt.oupjournals.org",false,true)) 623 | return "PROXY proxylib.ntou.edu.tw:3128"; 624 | if(check(host,"pm.nlx.com",false,true)) 625 | return "PROXY proxylib.ntou.edu.tw:3128"; 626 | if(check(host,"pm.nlx.com/xtf/search?browse-collections=true",false,true)) 627 | return "PROXY proxylib.ntou.edu.tw:3128"; 628 | if(check(host,"pof.aip.org",false,true)) 629 | return "PROXY proxylib.ntou.edu.tw:3128"; 630 | if(check(host,"pop.aip.org",false,true)) 631 | return "PROXY proxylib.ntou.edu.tw:3128"; 632 | if(check(host,"portal.acm.org",false,true)) 633 | return "PROXY proxylib.ntou.edu.tw:3128"; 634 | if(check(host,"portal.isiknowledge.com",false,true)) 635 | return "PROXY proxylib.ntou.edu.tw:3128"; 636 | if(check(host,"pqdd.sinica.edu.tw",false,true)) 637 | return "PROXY proxylib.ntou.edu.tw:3128"; 638 | if(check(host,"pra.aps.org",false,true)) 639 | return "PROXY proxylib.ntou.edu.tw:3128"; 640 | if(check(host,"prb.aps.org",false,true)) 641 | return "PROXY proxylib.ntou.edu.tw:3128"; 642 | if(check(host,"prc.aps.org",false,true)) 643 | return "PROXY proxylib.ntou.edu.tw:3128"; 644 | if(check(host,"prd.aps.org",false,true)) 645 | return "PROXY proxylib.ntou.edu.tw:3128"; 646 | if(check(host,"pre.aps.org",false,true)) 647 | return "PROXY proxylib.ntou.edu.tw:3128"; 648 | if(check(host,"prl.aps.org",false,true)) 649 | return "PROXY proxylib.ntou.edu.tw:3128"; 650 | if(check(host,"pro-twfubao.infolinker.com.tw",false,true)) 651 | return "PROXY proxylib.ntou.edu.tw:3128"; 652 | if(check(host,"prola.aps.org",false,true)) 653 | return "PROXY proxylib.ntou.edu.tw:3128"; 654 | if(check(host,"prola.library.cornell.edu",false,true)) 655 | return "PROXY proxylib.ntou.edu.tw:3128"; 656 | if(check(host,"proquest.umi.com",false,true)) 657 | return "PROXY proxylib.ntou.edu.tw:3128"; 658 | if(check(host,"proquest.uni.com",false,true)) 659 | return "PROXY proxylib.ntou.edu.tw:3128"; 660 | if(check(host,"protein.oupjournals.org",false,true)) 661 | return "PROXY proxylib.ntou.edu.tw:3128"; 662 | if(check(host,"ptr.oupjournals.org",false,true)) 663 | return "PROXY proxylib.ntou.edu.tw:3128"; 664 | if(check(host,"pubmed.oupjournals.org",false,true)) 665 | return "PROXY proxylib.ntou.edu.tw:3128"; 666 | if(check(host,"pubs.acs.org",false,true)) 667 | return "PROXY proxylib.ntou.edu.tw:3128"; 668 | if(check(host,"pubs.rsc.org",false,true)) 669 | return "PROXY proxylib.ntou.edu.tw:3128"; 670 | if(check(host,"pubs3.acs.org",false,true)) 671 | return "PROXY proxylib.ntou.edu.tw:3128"; 672 | if(check(host,"qjmed.oupjournals.org",false,true)) 673 | return "PROXY proxylib.ntou.edu.tw:3128"; 674 | if(check(host,"reading.udn.com",false,true)) 675 | return "PROXY proxylib.ntou.edu.tw:3128"; 676 | if(check(host,"readopac.ncl.edu.tw",false,true)) 677 | return "PROXY proxylib.ntou.edu.tw:3128"; 678 | if(check(host,"readopac2.ncl.edu.tw",false,true)) 679 | return "PROXY proxylib.ntou.edu.tw:3128"; 680 | if(check(host,"readopac3.ncl.edu.tw",false,true)) 681 | return "PROXY proxylib.ntou.edu.tw:3128"; 682 | if(check(host,"reference.kluweronline.com",false,true)) 683 | return "PROXY proxylib.ntou.edu.tw:3128"; 684 | if(check(host,"refworks.reference-global.com",false,true)) 685 | return "PROXY proxylib.ntou.edu.tw:3128"; 686 | if(check(host,"rfs.oupjournals.org",false,true)) 687 | return "PROXY proxylib.ntou.edu.tw:3128"; 688 | if(check(host,"rheumatology.oupjournals.org",false,true)) 689 | return "PROXY proxylib.ntou.edu.tw:3128"; 690 | if(check(host,"rmp.aps.org",false,true)) 691 | return "PROXY proxylib.ntou.edu.tw:3128"; 692 | if(check(host,"rsi.aip.org",false,true)) 693 | return "PROXY proxylib.ntou.edu.tw:3128"; 694 | if(check(host,"rss.webofknowledge.com",false,true)) 695 | return "PROXY proxylib.ntou.edu.tw:3128"; 696 | if(check(host,"schiller.chadwyck.co.uk",false,true)) 697 | return "PROXY proxylib.ntou.edu.tw:3128"; 698 | if(check(host,"sciencenow.sciencemag.org",false,true)) 699 | return "PROXY proxylib.ntou.edu.tw:3128"; 700 | if(check(host,"scifinder.cas.org",false,true)) 701 | return "PROXY proxylib.ntou.edu.tw:3128"; 702 | if(check(host,"scitation.aip.org",false,true)) 703 | return "PROXY proxylib.ntou.edu.tw:3128"; 704 | if(check(host,"sdos.ejournal.ascc.net",false,true)) 705 | return "PROXY proxylib.ntou.edu.tw:3128"; 706 | if(check(host,"search.ebscohost.com",false,true)) 707 | return "PROXY proxylib.ntou.edu.tw:3128"; 708 | if(check(host,"search.epnet.com",false,true)) 709 | return "PROXY proxylib.ntou.edu.tw:3128"; 710 | if(check(host,"search.isiknowledge.com",false,true)) 711 | return "PROXY proxylib.ntou.edu.tw:3128"; 712 | if(check(host,"search.proquest.com",false,true)) 713 | return "PROXY proxylib.ntou.edu.tw:3128"; 714 | if(check(host,"search.webofknowledge.com",false,true)) 715 | return "PROXY proxylib.ntou.edu.tw:3128"; 716 | if(check(host,"ser.oupjournals.org",false,true)) 717 | return "PROXY proxylib.ntou.edu.tw:3128"; 718 | if(check(host,"service.csa.com.tw",false,true)) 719 | return "PROXY proxylib.ntou.edu.tw:3128"; 720 | if(check(host,"service.flysheet.com.tw",false,true)) 721 | return "PROXY proxylib.ntou.edu.tw:3128"; 722 | if(check(host,"service.refworks.com.tw",false,true)) 723 | return "PROXY proxylib.ntou.edu.tw:3128"; 724 | if(check(host,"shmu.alexanderstreet.com",false,true)) 725 | return "PROXY proxylib.ntou.edu.tw:3128"; 726 | if(check(host,"site.ebrary.com",false,true)) 727 | return "PROXY proxylib.ntou.edu.tw:3128"; 728 | if(check(host,"soth.alexanderstreet.com",false,true)) 729 | return "PROXY proxylib.ntou.edu.tw:3128"; 730 | if(check(host,"sp.oupjournals.org",false,true)) 731 | return "PROXY proxylib.ntou.edu.tw:3128"; 732 | if(check(host,"springerlink.metapress.com",false,true)) 733 | return "PROXY proxylib.ntou.edu.tw:3128"; 734 | if(check(host,"ssjj.oupjournals.org",false,true)) 735 | return "PROXY proxylib.ntou.edu.tw:3128"; 736 | if(check(host,"stfb.ntl.edu.tw",false,true)) 737 | return "PROXY proxylib.ntou.edu.tw:3128"; 738 | if(check(host,"stfj.ntl.edu.tw",false,true)) 739 | return "PROXY proxylib.ntou.edu.tw:3128"; 740 | if(check(host,"sub3.webofknowledge.com",false,true)) 741 | return "PROXY proxylib.ntou.edu.tw:3128"; 742 | if(check(host,"survival.oupjournals.org",false,true)) 743 | return "PROXY proxylib.ntou.edu.tw:3128"; 744 | if(check(host,"sushi.webofknowledge.com",false,true)) 745 | return "PROXY proxylib.ntou.edu.tw:3128"; 746 | if(check(host,"swproxy.swetswise.com",false,true)) 747 | return "PROXY proxylib.ntou.edu.tw:3128"; 748 | if(check(host,"taebc.ebook.hyread.com.tw",false,true)) 749 | return "PROXY proxylib.ntou.edu.tw:3128"; 750 | if(check(host,"taebc.etailer.dpsl.net",false,true)) 751 | return "PROXY proxylib.ntou.edu.tw:3128"; 752 | if(check(host,"taebc.koobe.com.tw",false,true)) 753 | return "PROXY proxylib.ntou.edu.tw:3128"; 754 | if(check(host,"taebcmgh.sa.libraryandbook.net",false,true)) 755 | return "PROXY proxylib.ntou.edu.tw:3128"; 756 | if(check(host,"tandf.msgfocus.com",false,true)) 757 | return "PROXY proxylib.ntou.edu.tw:3128"; 758 | if(check(host,"tao.wordpedia.com",false,true)) 759 | return "PROXY proxylib.ntou.edu.tw:3128"; 760 | if(check(host,"tbmcdb.infolinker.com.tw",false,true)) 761 | return "PROXY proxylib.ntou.edu.tw:3128"; 762 | if(check(host,"tcsd.lib.ntu.edu.tw",false,true)) 763 | return "PROXY proxylib.ntou.edu.tw:3128"; 764 | if(check(host,"tebko.infolinker.com.tw",false,true)) 765 | return "PROXY proxylib.ntou.edu.tw:3128"; 766 | if(check(host,"tie.tier.org.tw",false,true)) 767 | return "PROXY proxylib.ntou.edu.tw:3128"; 768 | if(check(host,"toc.webofknowledge.com",false,true)) 769 | return "PROXY proxylib.ntou.edu.tw:3128"; 770 | if(check(host,"toc.webofknowledgev4.com",false,true)) 771 | return "PROXY proxylib.ntou.edu.tw:3128"; 772 | if(check(host,"tongji.oversea.cnki.net",false,true)) 773 | return "PROXY proxylib.ntou.edu.tw:3128"; 774 | if(check(host,"toxsci.oupjournals.org",false,true)) 775 | return "PROXY proxylib.ntou.edu.tw:3128"; 776 | if(check(host,"turs.infolinker.com.tw",false,true)) 777 | return "PROXY proxylib.ntou.edu.tw:3128"; 778 | if(check(host,"tw.magv.com",false,true)) 779 | return "PROXY proxylib.ntou.edu.tw:3128"; 780 | if(check(host,"twu-ind.wisenews.net.tw",false,true)) 781 | return "PROXY proxylib.ntou.edu.tw:3128"; 782 | if(check(host,"udndata.com",false,true)) 783 | return "PROXY proxylib.ntou.edu.tw:3128"; 784 | if(check(host,"udndata.com/library/fullpage",false,true)) 785 | return "PROXY proxylib.ntou.edu.tw:3128"; 786 | if(check(host,"ulej.stic.gov.tw",false,true)) 787 | return "PROXY proxylib.ntou.edu.tw:3128"; 788 | if(check(host,"vnweb.hwwilsonweb.com",false,true)) 789 | return "PROXY proxylib.ntou.edu.tw:3128"; 790 | if(check(host,"wber.oupjournals.org",false,true)) 791 | return "PROXY proxylib.ntou.edu.tw:3128"; 792 | if(check(host,"wbro.oupjournals.org",false,true)) 793 | return "PROXY proxylib.ntou.edu.tw:3128"; 794 | if(check(host,"wcs.webofknowledge.com",false,true)) 795 | return "PROXY proxylib.ntou.edu.tw:3128"; 796 | if(check(host,"web.a.ebscohost.com",false,true)) 797 | return "PROXY proxylib.ntou.edu.tw:3128"; 798 | if(check(host,"web.b.ebscohost.com",false,true)) 799 | return "PROXY proxylib.ntou.edu.tw:3128"; 800 | if(check(host,"web.c.ebscohost.com",false,true)) 801 | return "PROXY proxylib.ntou.edu.tw:3128"; 802 | if(check(host,"web.d.ebscohost.com",false,true)) 803 | return "PROXY proxylib.ntou.edu.tw:3128"; 804 | if(check(host,"web.e.ebscohost.com",false,true)) 805 | return "PROXY proxylib.ntou.edu.tw:3128"; 806 | if(check(host,"web.ebscohost.com",false,true)) 807 | return "PROXY proxylib.ntou.edu.tw:3128"; 808 | if(check(host,"web.lexis-nexis.com",false,true)) 809 | return "PROXY proxylib.ntou.edu.tw:3128"; 810 | if(check(host,"web17.epnet.com",false,true)) 811 | return "PROXY proxylib.ntou.edu.tw:3128"; 812 | if(check(host,"webofknowledge.com",false,true)) 813 | return "PROXY proxylib.ntou.edu.tw:3128"; 814 | if(check(host,"webofknowledge.com ",false,true)) 815 | return "PROXY proxylib.ntou.edu.tw:3128"; 816 | if(check(host,"wok-ws.isiknowledge.com",false,true)) 817 | return "PROXY proxylib.ntou.edu.tw:3128"; 818 | if(check(host,"wos.stic.gov.tw",false,true)) 819 | return "PROXY proxylib.ntou.edu.tw:3128"; 820 | if(check(host,"ws.isiknowledge.com",false,true)) 821 | return "PROXY proxylib.ntou.edu.tw:3128"; 822 | if(check(host,"www.acm.org",false,true)) 823 | return "PROXY proxylib.ntou.edu.tw:3128"; 824 | if(check(host,"www.agu.org",false,true)) 825 | return "PROXY proxylib.ntou.edu.tw:3128"; 826 | if(check(host,"www.airitiaci.com",false,true)) 827 | return "PROXY proxylib.ntou.edu.tw:3128"; 828 | if(check(host,"www.airitiaci.com/",false,true)) 829 | return "PROXY proxylib.ntou.edu.tw:3128"; 830 | if(check(host,"www.airitibooks.com",false,true)) 831 | return "PROXY proxylib.ntou.edu.tw:3128"; 832 | if(check(host,"www.airitilibrary.com",false,true)) 833 | return "PROXY proxylib.ntou.edu.tw:3128"; 834 | if(check(host,"www.airitinature.com",false,true)) 835 | return "PROXY proxylib.ntou.edu.tw:3128"; 836 | if(check(host,"www.annualreviews.org",false,true)) 837 | return "PROXY proxylib.ntou.edu.tw:3128"; 838 | if(check(host,"www.apabi.com",false,true)) 839 | return "PROXY proxylib.ntou.edu.tw:3128"; 840 | if(check(host,"www.apabi.com/cec",false,true)) 841 | return "PROXY proxylib.ntou.edu.tw:3128"; 842 | if(check(host,"www.ascelibrary.org",false,true)) 843 | return "PROXY proxylib.ntou.edu.tw:3128"; 844 | if(check(host,"www.asme.org",false,true)) 845 | return "PROXY proxylib.ntou.edu.tw:3128"; 846 | if(check(host,"www.astm.org",false,true)) 847 | return "PROXY proxylib.ntou.edu.tw:3128"; 848 | if(check(host,"www.atozmapsonline.com",false,true)) 849 | return "PROXY proxylib.ntou.edu.tw:3128"; 850 | if(check(host,"www.atoztheworld.com",false,true)) 851 | return "PROXY proxylib.ntou.edu.tw:3128"; 852 | if(check(host,"www.atozworldbusiness.com",false,true)) 853 | return "PROXY proxylib.ntou.edu.tw:3128"; 854 | if(check(host,"www.atozworldculture.com",false,true)) 855 | return "PROXY proxylib.ntou.edu.tw:3128"; 856 | if(check(host,"www.atozworldtrade.com",false,true)) 857 | return "PROXY proxylib.ntou.edu.tw:3128"; 858 | if(check(host,"www.atozworldtravel.com",false,true)) 859 | return "PROXY proxylib.ntou.edu.tw:3128"; 860 | if(check(host,"www.biolbull.org",false,true)) 861 | return "PROXY proxylib.ntou.edu.tw:3128"; 862 | if(check(host,"www.bioone.org",false,true)) 863 | return "PROXY proxylib.ntou.edu.tw:3128"; 864 | if(check(host,"www.blackwell-synergy.com",false,true)) 865 | return "PROXY proxylib.ntou.edu.tw:3128"; 866 | if(check(host,"www.brepolis.net",false,true)) 867 | return "PROXY proxylib.ntou.edu.tw:3128"; 868 | if(check(host,"www.bridgemaneducation.com",false,true)) 869 | return "PROXY proxylib.ntou.edu.tw:3128"; 870 | if(check(host,"www.bssaonline.org",false,true)) 871 | return "PROXY proxylib.ntou.edu.tw:3128"; 872 | if(check(host,"www.cairn.info",false,true)) 873 | return "PROXY proxylib.ntou.edu.tw:3128"; 874 | if(check(host,"www.ceps.com.tw",false,true)) 875 | return "PROXY proxylib.ntou.edu.tw:3128"; 876 | if(check(host,"www.chinamaxx.net",false,true)) 877 | return "PROXY proxylib.ntou.edu.tw:3128"; 878 | if(check(host,"www.classiques-garnier.com",false,true)) 879 | return "PROXY proxylib.ntou.edu.tw:3128"; 880 | if(check(host,"www.cnsonline.com.tw",false,true)) 881 | return "PROXY proxylib.ntou.edu.tw:3128"; 882 | if(check(host,"www.cnsppa.com.tw",false,true)) 883 | return "PROXY proxylib.ntou.edu.tw:3128"; 884 | if(check(host,"www.crcnetbase.com",false,true)) 885 | return "PROXY proxylib.ntou.edu.tw:3128"; 886 | if(check(host,"www.credoreference.com",false,true)) 887 | return "PROXY proxylib.ntou.edu.tw:3128"; 888 | if(check(host,"www.csa.com",false,true)) 889 | return "PROXY proxylib.ntou.edu.tw:3128"; 890 | if(check(host,"www.csa.com.tw",false,true)) 891 | return "PROXY proxylib.ntou.edu.tw:3128"; 892 | if(check(host,"www.dalloz.fr",false,true)) 893 | return "PROXY proxylib.ntou.edu.tw:3128"; 894 | if(check(host,"www.dialogselect.com",false,true)) 895 | return "PROXY proxylib.ntou.edu.tw:3128"; 896 | if(check(host,"www.discoverygate.com",false,true)) 897 | return "PROXY proxylib.ntou.edu.tw:3128"; 898 | if(check(host,"www.duxiu.com",false,true)) 899 | return "PROXY proxylib.ntou.edu.tw:3128"; 900 | if(check(host,"www.ebookstore.tandf.co.uk",false,true)) 901 | return "PROXY proxylib.ntou.edu.tw:3128"; 902 | if(check(host,"www.ebsco.com",false,true)) 903 | return "PROXY proxylib.ntou.edu.tw:3128"; 904 | if(check(host,"www.educationarena.com",false,true)) 905 | return "PROXY proxylib.ntou.edu.tw:3128"; 906 | if(check(host,"www.ei.org",false,true)) 907 | return "PROXY proxylib.ntou.edu.tw:3128"; 908 | if(check(host,"www.els.net",false,true)) 909 | return "PROXY proxylib.ntou.edu.tw:3128"; 910 | if(check(host,"www.elsevier.com",false,true)) 911 | return "PROXY proxylib.ntou.edu.tw:3128"; 912 | if(check(host,"www.emeraldinsight.com",false,true)) 913 | return "PROXY proxylib.ntou.edu.tw:3128"; 914 | if(check(host,"www.engineeringvillage.com",false,true)) 915 | return "PROXY proxylib.ntou.edu.tw:3128"; 916 | if(check(host,"www.engineeringvillage2.org",false,true)) 917 | return "PROXY proxylib.ntou.edu.tw:3128"; 918 | if(check(host,"www.europaworld.com",false,true)) 919 | return "PROXY proxylib.ntou.edu.tw:3128"; 920 | if(check(host,"www.europe.idealibrary.com",false,true)) 921 | return "PROXY proxylib.ntou.edu.tw:3128"; 922 | if(check(host,"www.frantext.fr",false,true)) 923 | return "PROXY proxylib.ntou.edu.tw:3128"; 924 | if(check(host,"www.genome.org",false,true)) 925 | return "PROXY proxylib.ntou.edu.tw:3128"; 926 | if(check(host,"www.genomebiology.com",false,true)) 927 | return "PROXY proxylib.ntou.edu.tw:3128"; 928 | if(check(host,"www.greeninfoonline.com",false,true)) 929 | return "PROXY proxylib.ntou.edu.tw:3128"; 930 | if(check(host,"www.hepseu.com",false,true)) 931 | return "PROXY proxylib.ntou.edu.tw:3128"; 932 | if(check(host,"www.icevirtuallibrary.com",false,true)) 933 | return "PROXY proxylib.ntou.edu.tw:3128"; 934 | if(check(host,"www.idealibrary.com",false,true)) 935 | return "PROXY proxylib.ntou.edu.tw:3128"; 936 | if(check(host,"www.igpublish.com",false,true)) 937 | return "PROXY proxylib.ntou.edu.tw:3128"; 938 | if(check(host,"www.informaworld.com",false,true)) 939 | return "PROXY proxylib.ntou.edu.tw:3128"; 940 | if(check(host,"www.ingenta.com",false,true)) 941 | return "PROXY proxylib.ntou.edu.tw:3128"; 942 | if(check(host,"www.int-res.com",false,true)) 943 | return "PROXY proxylib.ntou.edu.tw:3128"; 944 | if(check(host,"www.iop.org",false,true)) 945 | return "PROXY proxylib.ntou.edu.tw:3128"; 946 | if(check(host,"www.iospress.nl",false,true)) 947 | return "PROXY proxylib.ntou.edu.tw:3128"; 948 | if(check(host,"www.isihighlycited.com",false,true)) 949 | return "PROXY proxylib.ntou.edu.tw:3128"; 950 | if(check(host,"www.jkn21.com",false,true)) 951 | return "PROXY proxylib.ntou.edu.tw:3128"; 952 | if(check(host,"www.jstor.org",false,true)) 953 | return "PROXY proxylib.ntou.edu.tw:3128"; 954 | if(check(host,"www.juris.de",false,true)) 955 | return "PROXY proxylib.ntou.edu.tw:3128"; 956 | if(check(host,"www.kluwerlawonline.com",false,true)) 957 | return "PROXY proxylib.ntou.edu.tw:3128"; 958 | if(check(host,"www.kluweronline.com",false,true)) 959 | return "PROXY proxylib.ntou.edu.tw:3128"; 960 | if(check(host,"www.knovel.com",false,true)) 961 | return "PROXY proxylib.ntou.edu.tw:3128"; 962 | if(check(host,"www.lawbank.com.tw",false,true)) 963 | return "PROXY proxylib.ntou.edu.tw:3128"; 964 | if(check(host,"www.lawdata.com.tw",false,true)) 965 | return "PROXY proxylib.ntou.edu.tw:3128"; 966 | if(check(host,"www.lexisnexis.com",false,true)) 967 | return "PROXY proxylib.ntou.edu.tw:3128"; 968 | if(check(host,"www.lexisnexis.com/ap/academic",false,true)) 969 | return "PROXY proxylib.ntou.edu.tw:3128"; 970 | if(check(host,"www.lexisnexis.com/ap/auth",false,true)) 971 | return "PROXY proxylib.ntou.edu.tw:3128"; 972 | if(check(host,"www.lextenso.fr",false,true)) 973 | return "PROXY proxylib.ntou.edu.tw:3128"; 974 | if(check(host,"www.mergentonline.com",false,true)) 975 | return "PROXY proxylib.ntou.edu.tw:3128"; 976 | if(check(host,"www.mrw.interscience.wiley.com",false,true)) 977 | return "PROXY proxylib.ntou.edu.tw:3128"; 978 | if(check(host,"www.munzinger.de",false,true)) 979 | return "PROXY proxylib.ntou.edu.tw:3128"; 980 | if(check(host,"www.myendnoteweb.com",false,true)) 981 | return "PROXY proxylib.ntou.edu.tw:3128"; 982 | if(check(host,"www.myilibrary.com",false,true)) 983 | return "PROXY proxylib.ntou.edu.tw:3128"; 984 | if(check(host,"www.nature.com",false,true)) 985 | return "PROXY proxylib.ntou.edu.tw:3128"; 986 | if(check(host,"www.netlibrary.com",false,true)) 987 | return "PROXY proxylib.ntou.edu.tw:3128"; 988 | if(check(host,"www.nonlin-processes-geophys.net",false,true)) 989 | return "PROXY proxylib.ntou.edu.tw:3128"; 990 | if(check(host,"www.nutrition.org",false,true)) 991 | return "PROXY proxylib.ntou.edu.tw:3128"; 992 | if(check(host,"www.onesource.com",false,true)) 993 | return "PROXY proxylib.ntou.edu.tw:3128"; 994 | if(check(host,"www.opticsexpress.org",false,true)) 995 | return "PROXY proxylib.ntou.edu.tw:3128"; 996 | if(check(host,"www.osa-jon.org",false,true)) 997 | return "PROXY proxylib.ntou.edu.tw:3128"; 998 | if(check(host,"www.osa-opn.org",false,true)) 999 | return "PROXY proxylib.ntou.edu.tw:3128"; 1000 | if(check(host,"www.oxfordreference.com",false,true)) 1001 | return "PROXY proxylib.ntou.edu.tw:3128"; 1002 | if(check(host,"www.oxfordscholarship.com",false,true)) 1003 | return "PROXY proxylib.ntou.edu.tw:3128"; 1004 | if(check(host,"www.palgrave-journals.com",false,true)) 1005 | return "PROXY proxylib.ntou.edu.tw:3128"; 1006 | if(check(host,"www.palgraveconnect.com",false,true)) 1007 | return "PROXY proxylib.ntou.edu.tw:3128"; 1008 | if(check(host,"www.proteinscience.org",false,true)) 1009 | return "PROXY proxylib.ntou.edu.tw:3128"; 1010 | if(check(host,"www.read.com.tw",false,true)) 1011 | return "PROXY proxylib.ntou.edu.tw:3128"; 1012 | if(check(host,"www.reaxys.com",false,true)) 1013 | return "PROXY proxylib.ntou.edu.tw:3128"; 1014 | if(check(host,"www.refworks.com",false,true)) 1015 | return "PROXY proxylib.ntou.edu.tw:3128"; 1016 | if(check(host,"www.refworks.com.tw",false,true)) 1017 | return "PROXY proxylib.ntou.edu.tw:3128"; 1018 | if(check(host,"www.researcherid.com",false,true)) 1019 | return "PROXY proxylib.ntou.edu.tw:3128"; 1020 | if(check(host,"www.rsc.org",false,true)) 1021 | return "PROXY proxylib.ntou.edu.tw:3128"; 1022 | if(check(host,"www.sage-ereference.com",false,true)) 1023 | return "PROXY proxylib.ntou.edu.tw:3128"; 1024 | if(check(host,"www.sciencedirect.com",false,true)) 1025 | return "PROXY proxylib.ntou.edu.tw:3128"; 1026 | if(check(host,"www.sciencemag.org",false,true)) 1027 | return "PROXY proxylib.ntou.edu.tw:3128"; 1028 | if(check(host,"www.scopus.com",false,true)) 1029 | return "PROXY proxylib.ntou.edu.tw:3128"; 1030 | if(check(host,"www.springerlink.com",false,true)) 1031 | return "PROXY proxylib.ntou.edu.tw:3128"; 1032 | if(check(host,"www.swetsnet.nl",false,true)) 1033 | return "PROXY proxylib.ntou.edu.tw:3128"; 1034 | if(check(host,"www.swetswise.com",false,true)) 1035 | return "PROXY proxylib.ntou.edu.tw:3128"; 1036 | if(check(host,"www.taebcnetbase.com",false,true)) 1037 | return "PROXY proxylib.ntou.edu.tw:3128"; 1038 | if(check(host,"www.tandf.co.uk",false,true)) 1039 | return "PROXY proxylib.ntou.edu.tw:3128"; 1040 | if(check(host,"www.tandfonline.com",false,true)) 1041 | return "PROXY proxylib.ntou.edu.tw:3128"; 1042 | if(check(host,"www.tbmc.com.tw",false,true)) 1043 | return "PROXY proxylib.ntou.edu.tw:3128"; 1044 | if(check(host,"www.TeacherReference.com",false,true)) 1045 | return "PROXY proxylib.ntou.edu.tw:3128"; 1046 | if(check(host,"www.tlemea.com",false,true)) 1047 | return "PROXY proxylib.ntou.edu.tw:3128"; 1048 | if(check(host,"www.tls.psmedia.com",false,true)) 1049 | return "PROXY proxylib.ntou.edu.tw:3128"; 1050 | if(check(host,"www.tumblebooks.com",false,true)) 1051 | return "PROXY proxylib.ntou.edu.tw:3128"; 1052 | if(check(host,"www.tw-elsevier.com",false,true)) 1053 | return "PROXY proxylib.ntou.edu.tw:3128"; 1054 | if(check(host,"www.universalis-edu.com",false,true)) 1055 | return "PROXY proxylib.ntou.edu.tw:3128"; 1056 | if(check(host,"www.wanfangdata.com.hk",false,true)) 1057 | return "PROXY proxylib.ntou.edu.tw:3128"; 1058 | if(check(host,"www.webofknowledge.com",false,true)) 1059 | return "PROXY proxylib.ntou.edu.tw:3128"; 1060 | if(check(host,"www.webofknowledgev4.com",false,true)) 1061 | return "PROXY proxylib.ntou.edu.tw:3128"; 1062 | if(check(host,"www.westlaw.com",false,true)) 1063 | return "PROXY proxylib.ntou.edu.tw:3128"; 1064 | if(check(host,"www.wkap.nl",false,true)) 1065 | return "PROXY proxylib.ntou.edu.tw:3128"; 1066 | if(check(host,"www2.astm.org",false,true)) 1067 | return "PROXY proxylib.ntou.edu.tw:3128"; 1068 | if(check(host,"www2.read.com.tw",false,true)) 1069 | return "PROXY proxylib.ntou.edu.tw:3128"; 1070 | if(check(host,"www3.electrochem.org",false,true)) 1071 | return "PROXY proxylib.ntou.edu.tw:3128"; 1072 | if(check(host,"www3.interscience.wiley.com",false,true)) 1073 | return "PROXY proxylib.ntou.edu.tw:3128"; 1074 | if(check(host,"www3.oup.co.uk",false,true)) 1075 | return "PROXY proxylib.ntou.edu.tw:3128"; 1076 | if(check(host,"wwwlib.global.umi.com",false,true)) 1077 | return "PROXY proxylib.ntou.edu.tw:3128"; 1078 | if(check(host,"yagi.jkn21.com",false,true)) 1079 | return "PROXY proxylib.ntou.edu.tw:3128"; 1080 | return "DIRECT"; 1081 | } 1082 | function check(target,term,caseSens,wordOnly) { 1083 | if (!caseSens) { 1084 | term = term.toLowerCase(); 1085 | target = target.toLowerCase(); 1086 | } 1087 | if(target.indexOf(term) >= 0) { 1088 | return true; 1089 | } 1090 | return false; 1091 | } 1092 | -------------------------------------------------------------------------------- /tests/3.js: -------------------------------------------------------------------------------- 1 | function FindProxyForURL(url, host) { 2 | // our local URLs from the domains below example.com don't need a proxy: 3 | if (shExpMatch(host, "*.example.com")) { 4 | return "DIRECT"; 5 | } 6 | 7 | // URLs within this network are accessed through 8 | // port 8080 on fastproxy.example.com: 9 | if (isInNet(host, "10.0.0.0", "255.255.248.0")) { 10 | return "PROXY fastproxy.example.com:8080"; 11 | } 12 | 13 | // All other requests go through port 8080 of proxy.example.com. 14 | // should that fail to respond, go directly to the WWW: 15 | return "PROXY proxy.example.com:8080; DIRECT"; 16 | } 17 | -------------------------------------------------------------------------------- /tests/4.js: -------------------------------------------------------------------------------- 1 | function FindProxyForURL(url, host) { 2 | throw 'testing error handling, url: ' + url + ' host: ' + host; 3 | } 4 | -------------------------------------------------------------------------------- /tests/5.js: -------------------------------------------------------------------------------- 1 | function FindProxyForURL(url, host) { 2 | throw new Error('testing error handling, url: ' + url + ' host: ' + host); 3 | } 4 | -------------------------------------------------------------------------------- /tests/6.js: -------------------------------------------------------------------------------- 1 | function FindProxyForURL(url, host) { 2 | ip = dnsResolve(host); 3 | return "PROXY " + ip + ":8080"; 4 | } 5 | -------------------------------------------------------------------------------- /tests/Makefile.am: -------------------------------------------------------------------------------- 1 | ACLOCAL_AMFLAGS = -I m4 2 | 3 | AM_CPPFLAGS = -I$(top_builddir) -I$(top_srcdir) \ 4 | -I$(top_builddir)/include -I$(top_srcdir)/include \ 5 | @LOCAL_CPPFLAGS@ $(EXTRA_CPPFLAGS) 6 | AM_LDFLAGS = @LOCAL_LDFLAGS@ $(EXTRA_LDFLAGS) 7 | 8 | LIBS += $(EXTRA_LIBS) ../libpac.la 9 | 10 | check_PROGRAMS = test_unit1 test_unit2 test_unit3 11 | 12 | noinst_PROGRAMS = test_pac 13 | test_pac_SOURCES = test_pac.c 14 | test_pac_CPPFLAGS = $(AM_CPPFLAGS) 15 | 16 | TESTS = test_unit1 \ 17 | test_unit2 \ 18 | test_unit3 \ 19 | test1.sh \ 20 | test2.sh \ 21 | test3.sh \ 22 | test4.sh \ 23 | test5.sh \ 24 | test6.sh 25 | 26 | test_unit1_SOURCES = test_unit1.c 27 | 28 | test_unit2_SOURCES = test_unit2.c 29 | 30 | test_unit3_SOURCES = test_unit3.c 31 | -------------------------------------------------------------------------------- /tests/greatest.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2011 Scott Vokes 3 | * 4 | * Permission to use, copy, modify, and/or distribute this software for any 5 | * purpose with or without fee is hereby granted, provided that the above 6 | * copyright notice and this permission notice appear in all copies. 7 | * 8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 9 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 10 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 11 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 12 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 13 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 14 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 15 | */ 16 | 17 | #ifndef GREATEST_H 18 | #define GREATEST_H 19 | 20 | #define GREATEST_VERSION_MAJOR 0 21 | #define GREATEST_VERSION_MINOR 9 22 | #define GREATEST_VERSION_PATCH 3 23 | 24 | /* A unit testing system for C, contained in 1 file. 25 | * It doesn't use dynamic allocation or depend on anything 26 | * beyond ANSI C89. */ 27 | 28 | 29 | /********************************************************************* 30 | * Minimal test runner template 31 | *********************************************************************/ 32 | #if 0 33 | 34 | #include "greatest.h" 35 | 36 | TEST foo_should_foo() { 37 | PASS(); 38 | } 39 | 40 | static void setup_cb(void *data) { 41 | printf("setup callback for each test case\n"); 42 | } 43 | 44 | static void teardown_cb(void *data) { 45 | printf("teardown callback for each test case\n"); 46 | } 47 | 48 | SUITE(suite) { 49 | /* Optional setup/teardown callbacks which will be run before/after 50 | * every test case in the suite. 51 | * Cleared when the suite finishes. */ 52 | SET_SETUP(setup_cb, voidp_to_callback_data); 53 | SET_TEARDOWN(teardown_cb, voidp_to_callback_data); 54 | 55 | RUN_TEST(foo_should_foo); 56 | } 57 | 58 | /* Add all the definitions that need to be in the test runner's main file. */ 59 | GREATEST_MAIN_DEFS(); 60 | 61 | int main(int argc, char **argv) { 62 | GREATEST_MAIN_BEGIN(); /* command-line arguments, initialization. */ 63 | RUN_SUITE(suite); 64 | GREATEST_MAIN_END(); /* display results */ 65 | } 66 | 67 | #endif 68 | /*********************************************************************/ 69 | 70 | 71 | #include 72 | #include 73 | #include 74 | #include 75 | 76 | 77 | /*********** 78 | * Options * 79 | ***********/ 80 | 81 | /* Default column width for non-verbose output. */ 82 | #ifndef GREATEST_DEFAULT_WIDTH 83 | #define GREATEST_DEFAULT_WIDTH 72 84 | #endif 85 | 86 | /* FILE *, for test logging. */ 87 | #ifndef GREATEST_STDOUT 88 | #define GREATEST_STDOUT stdout 89 | #endif 90 | 91 | /* Remove GREATEST_ prefix from most commonly used symbols? */ 92 | #ifndef GREATEST_USE_ABBREVS 93 | #define GREATEST_USE_ABBREVS 1 94 | #endif 95 | 96 | 97 | /********* 98 | * Types * 99 | *********/ 100 | 101 | /* Info for the current running suite. */ 102 | typedef struct greatest_suite_info { 103 | unsigned int tests_run; 104 | unsigned int passed; 105 | unsigned int failed; 106 | unsigned int skipped; 107 | 108 | /* timers, pre/post running suite and individual tests */ 109 | clock_t pre_suite; 110 | clock_t post_suite; 111 | clock_t pre_test; 112 | clock_t post_test; 113 | } greatest_suite_info; 114 | 115 | /* Type for a suite function. */ 116 | typedef void (greatest_suite_cb)(void); 117 | 118 | /* Types for setup/teardown callbacks. If non-NULL, these will be run 119 | * and passed the pointer to their additional data. */ 120 | typedef void (greatest_setup_cb)(void *udata); 121 | typedef void (greatest_teardown_cb)(void *udata); 122 | 123 | typedef enum { 124 | GREATEST_FLAG_VERBOSE = 0x01, 125 | GREATEST_FLAG_FIRST_FAIL = 0x02, 126 | GREATEST_FLAG_LIST_ONLY = 0x04 127 | } GREATEST_FLAG; 128 | 129 | typedef struct greatest_run_info { 130 | unsigned int flags; 131 | unsigned int tests_run; /* total test count */ 132 | 133 | /* Overall pass/fail/skip counts. */ 134 | unsigned int passed; 135 | unsigned int failed; 136 | unsigned int skipped; 137 | 138 | /* currently running test suite */ 139 | greatest_suite_info suite; 140 | 141 | /* info to print about the most recent failure */ 142 | const char *fail_file; 143 | unsigned int fail_line; 144 | const char *msg; 145 | 146 | /* current setup/teardown hooks and userdata */ 147 | greatest_setup_cb *setup; 148 | void *setup_udata; 149 | greatest_teardown_cb *teardown; 150 | void *teardown_udata; 151 | 152 | /* formatting info for ".....s...F"-style output */ 153 | unsigned int col; 154 | unsigned int width; 155 | 156 | /* only run a specific suite or test */ 157 | char *suite_filter; 158 | char *test_filter; 159 | 160 | /* overall timers */ 161 | clock_t begin; 162 | clock_t end; 163 | } greatest_run_info; 164 | 165 | /* Global var for the current testing context. 166 | * Initialized by GREATEST_MAIN_DEFS(). */ 167 | extern greatest_run_info greatest_info; 168 | 169 | 170 | /********************** 171 | * Exported functions * 172 | **********************/ 173 | 174 | void greatest_do_pass(const char *name); 175 | void greatest_do_fail(const char *name); 176 | void greatest_do_skip(const char *name); 177 | int greatest_pre_test(const char *name); 178 | void greatest_post_test(const char *name, int res); 179 | void greatest_usage(const char *name); 180 | void GREATEST_SET_SETUP_CB(greatest_setup_cb *cb, void *udata); 181 | void GREATEST_SET_TEARDOWN_CB(greatest_teardown_cb *cb, void *udata); 182 | 183 | 184 | /********** 185 | * Macros * 186 | **********/ 187 | 188 | /* Define a suite. */ 189 | #define GREATEST_SUITE(NAME) void NAME(void) 190 | 191 | /* Start defining a test function. 192 | * The arguments are not included, to allow parametric testing. */ 193 | #define GREATEST_TEST static int 194 | 195 | /* Run a suite. */ 196 | #define GREATEST_RUN_SUITE(S_NAME) greatest_run_suite(S_NAME, #S_NAME) 197 | 198 | /* Run a test in the current suite. */ 199 | #define GREATEST_RUN_TEST(TEST) \ 200 | do { \ 201 | if (greatest_pre_test(#TEST) == 1) { \ 202 | int res = TEST(); \ 203 | greatest_post_test(#TEST, res); \ 204 | } else if (GREATEST_LIST_ONLY()) { \ 205 | fprintf(GREATEST_STDOUT, " %s\n", #TEST); \ 206 | } \ 207 | } while (0) 208 | 209 | /* Run a test in the current suite with one void* argument, 210 | * which can be a pointer to a struct with multiple arguments. */ 211 | #define GREATEST_RUN_TEST1(TEST, ENV) \ 212 | do { \ 213 | if (greatest_pre_test(#TEST) == 1) { \ 214 | int res = TEST(ENV); \ 215 | greatest_post_test(#TEST, res); \ 216 | } else if (GREATEST_LIST_ONLY()) { \ 217 | fprintf(GREATEST_STDOUT, " %s\n", #TEST); \ 218 | } \ 219 | } while (0) 220 | 221 | /* If __VA_ARGS__ (C99) is supported, allow parametric testing 222 | * without needing to manually manage the argument struct. */ 223 | #if __STDC_VERSION__ >= 19901L 224 | #define GREATEST_RUN_TESTp(TEST, ...) \ 225 | do { \ 226 | if (greatest_pre_test(#TEST) == 1) { \ 227 | int res = TEST(__VA_ARGS__); \ 228 | greatest_post_test(#TEST, res); \ 229 | } else if (GREATEST_LIST_ONLY()) { \ 230 | fprintf(GREATEST_STDOUT, " %s\n", #TEST); \ 231 | } \ 232 | } while (0) 233 | #endif 234 | 235 | 236 | /* Check if the test runner is in verbose mode. */ 237 | #define GREATEST_IS_VERBOSE() (greatest_info.flags & GREATEST_FLAG_VERBOSE) 238 | #define GREATEST_LIST_ONLY() (greatest_info.flags & GREATEST_FLAG_LIST_ONLY) 239 | #define GREATEST_FIRST_FAIL() (greatest_info.flags & GREATEST_FLAG_FIRST_FAIL) 240 | #define GREATEST_FAILURE_ABORT() (greatest_info.suite.failed > 0 && GREATEST_FIRST_FAIL()) 241 | 242 | /* Message-less forms. */ 243 | #define GREATEST_PASS() GREATEST_PASSm(NULL) 244 | #define GREATEST_FAIL() GREATEST_FAILm(NULL) 245 | #define GREATEST_SKIP() GREATEST_SKIPm(NULL) 246 | #define GREATEST_ASSERT(COND) GREATEST_ASSERTm(#COND, COND) 247 | #define GREATEST_ASSERT_FALSE(COND) GREATEST_ASSERT_FALSEm(#COND, COND) 248 | #define GREATEST_ASSERT_EQ(EXP, GOT) GREATEST_ASSERT_EQm(#EXP " != " #GOT, EXP, GOT) 249 | #define GREATEST_ASSERT_STR_EQ(EXP, GOT) GREATEST_ASSERT_STR_EQm(#EXP " != " #GOT, EXP, GOT) 250 | 251 | /* The following forms take an additional message argument first, 252 | * to be displayed by the test runner. */ 253 | 254 | /* Fail if a condition is not true, with message. */ 255 | #define GREATEST_ASSERTm(MSG, COND) \ 256 | do { \ 257 | greatest_info.msg = MSG; \ 258 | greatest_info.fail_file = __FILE__; \ 259 | greatest_info.fail_line = __LINE__; \ 260 | if (!(COND)) return -1; \ 261 | greatest_info.msg = NULL; \ 262 | } while (0) 263 | 264 | #define GREATEST_ASSERT_FALSEm(MSG, COND) \ 265 | do { \ 266 | greatest_info.msg = MSG; \ 267 | greatest_info.fail_file = __FILE__; \ 268 | greatest_info.fail_line = __LINE__; \ 269 | if ((COND)) return -1; \ 270 | greatest_info.msg = NULL; \ 271 | } while (0) 272 | 273 | #define GREATEST_ASSERT_EQm(MSG, EXP, GOT) \ 274 | do { \ 275 | greatest_info.msg = MSG; \ 276 | greatest_info.fail_file = __FILE__; \ 277 | greatest_info.fail_line = __LINE__; \ 278 | if ((EXP) != (GOT)) return -1; \ 279 | greatest_info.msg = NULL; \ 280 | } while (0) 281 | 282 | #define GREATEST_ASSERT_STR_EQm(MSG, EXP, GOT) \ 283 | do { \ 284 | const char *exp_s = (EXP); \ 285 | const char *got_s = (GOT); \ 286 | greatest_info.msg = MSG; \ 287 | greatest_info.fail_file = __FILE__; \ 288 | greatest_info.fail_line = __LINE__; \ 289 | if (0 != strcmp(exp_s, got_s)) { \ 290 | fprintf(GREATEST_STDOUT, \ 291 | "Expected:\n####\n%s\n####\n", exp_s); \ 292 | fprintf(GREATEST_STDOUT, \ 293 | "Got:\n####\n%s\n####\n", got_s); \ 294 | return -1; \ 295 | } \ 296 | greatest_info.msg = NULL; \ 297 | } while (0) 298 | 299 | #define GREATEST_PASSm(MSG) \ 300 | do { \ 301 | greatest_info.msg = MSG; \ 302 | return 0; \ 303 | } while (0) 304 | 305 | #define GREATEST_FAILm(MSG) \ 306 | do { \ 307 | greatest_info.fail_file = __FILE__; \ 308 | greatest_info.fail_line = __LINE__; \ 309 | greatest_info.msg = MSG; \ 310 | return -1; \ 311 | } while (0) 312 | 313 | #define GREATEST_SKIPm(MSG) \ 314 | do { \ 315 | greatest_info.msg = MSG; \ 316 | return 1; \ 317 | } while (0) 318 | 319 | #define GREATEST_SET_TIME(NAME) \ 320 | NAME = clock(); \ 321 | if (NAME == (clock_t) -1) { \ 322 | fprintf(GREATEST_STDOUT, \ 323 | "clock error: %s\n", #NAME); \ 324 | exit(EXIT_FAILURE); \ 325 | } 326 | 327 | #define GREATEST_CLOCK_DIFF(C1, C2) \ 328 | fprintf(GREATEST_STDOUT, " (%lu ticks, %.3f sec)", \ 329 | (long unsigned int) (C2) - (C1), \ 330 | (double)((C2) - (C1)) / (1.0 * (double)CLOCKS_PER_SEC)) \ 331 | 332 | /* Include several function definitions in the main test file. */ 333 | #define GREATEST_MAIN_DEFS() \ 334 | \ 335 | /* Is FILTER a subset of NAME? */ \ 336 | static int greatest_name_match(const char *name, \ 337 | const char *filter) { \ 338 | size_t offset = 0; \ 339 | size_t filter_len = strlen(filter); \ 340 | while (name[offset] != '\0') { \ 341 | if (name[offset] == filter[0]) { \ 342 | if (0 == strncmp(&name[offset], filter, filter_len)) { \ 343 | return 1; \ 344 | } \ 345 | } \ 346 | offset++; \ 347 | } \ 348 | \ 349 | return 0; \ 350 | } \ 351 | \ 352 | int greatest_pre_test(const char *name) { \ 353 | if (!GREATEST_LIST_ONLY() \ 354 | && (!GREATEST_FIRST_FAIL() || greatest_info.suite.failed == 0) \ 355 | && (greatest_info.test_filter == NULL || \ 356 | greatest_name_match(name, greatest_info.test_filter))) { \ 357 | GREATEST_SET_TIME(greatest_info.suite.pre_test); \ 358 | if (greatest_info.setup) { \ 359 | greatest_info.setup(greatest_info.setup_udata); \ 360 | } \ 361 | return 1; /* test should be run */ \ 362 | } else { \ 363 | return 0; /* skipped */ \ 364 | } \ 365 | } \ 366 | \ 367 | void greatest_post_test(const char *name, int res) { \ 368 | GREATEST_SET_TIME(greatest_info.suite.post_test); \ 369 | if (greatest_info.teardown) { \ 370 | void *udata = greatest_info.teardown_udata; \ 371 | greatest_info.teardown(udata); \ 372 | } \ 373 | \ 374 | if (res < 0) { \ 375 | greatest_do_fail(name); \ 376 | } else if (res > 0) { \ 377 | greatest_do_skip(name); \ 378 | } else if (res == 0) { \ 379 | greatest_do_pass(name); \ 380 | } \ 381 | greatest_info.suite.tests_run++; \ 382 | greatest_info.col++; \ 383 | if (GREATEST_IS_VERBOSE()) { \ 384 | GREATEST_CLOCK_DIFF(greatest_info.suite.pre_test, \ 385 | greatest_info.suite.post_test); \ 386 | fprintf(GREATEST_STDOUT, "\n"); \ 387 | } else if (greatest_info.col % greatest_info.width == 0) { \ 388 | fprintf(GREATEST_STDOUT, "\n"); \ 389 | greatest_info.col = 0; \ 390 | } \ 391 | if (GREATEST_STDOUT == stdout) fflush(stdout); \ 392 | } \ 393 | \ 394 | static void greatest_run_suite(greatest_suite_cb *suite_cb, \ 395 | const char *suite_name) { \ 396 | if (greatest_info.suite_filter && \ 397 | !greatest_name_match(suite_name, greatest_info.suite_filter)) \ 398 | return; \ 399 | if (GREATEST_FIRST_FAIL() && greatest_info.failed > 0) return; \ 400 | greatest_info.suite.tests_run = 0; \ 401 | greatest_info.suite.failed = 0; \ 402 | greatest_info.suite.passed = 0; \ 403 | greatest_info.suite.skipped = 0; \ 404 | greatest_info.suite.pre_suite = 0; \ 405 | greatest_info.suite.post_suite = 0; \ 406 | greatest_info.suite.pre_test = 0; \ 407 | greatest_info.suite.post_test = 0; \ 408 | greatest_info.col = 0; \ 409 | fprintf(GREATEST_STDOUT, "\n* Suite %s:\n", suite_name); \ 410 | GREATEST_SET_TIME(greatest_info.suite.pre_suite); \ 411 | suite_cb(); \ 412 | GREATEST_SET_TIME(greatest_info.suite.post_suite); \ 413 | if (greatest_info.suite.tests_run > 0) { \ 414 | fprintf(GREATEST_STDOUT, \ 415 | "\n%u tests - %u pass, %u fail, %u skipped", \ 416 | greatest_info.suite.tests_run, \ 417 | greatest_info.suite.passed, \ 418 | greatest_info.suite.failed, \ 419 | greatest_info.suite.skipped); \ 420 | GREATEST_CLOCK_DIFF(greatest_info.suite.pre_suite, \ 421 | greatest_info.suite.post_suite); \ 422 | fprintf(GREATEST_STDOUT, "\n"); \ 423 | } \ 424 | greatest_info.setup = NULL; \ 425 | greatest_info.setup_udata = NULL; \ 426 | greatest_info.teardown = NULL; \ 427 | greatest_info.teardown_udata = NULL; \ 428 | greatest_info.passed += greatest_info.suite.passed; \ 429 | greatest_info.failed += greatest_info.suite.failed; \ 430 | greatest_info.skipped += greatest_info.suite.skipped; \ 431 | greatest_info.tests_run += greatest_info.suite.tests_run; \ 432 | } \ 433 | \ 434 | void greatest_do_pass(const char *name) { \ 435 | if (GREATEST_IS_VERBOSE()) { \ 436 | fprintf(GREATEST_STDOUT, "PASS %s: %s", \ 437 | name, greatest_info.msg ? greatest_info.msg : ""); \ 438 | } else { \ 439 | fprintf(GREATEST_STDOUT, "."); \ 440 | } \ 441 | greatest_info.suite.passed++; \ 442 | } \ 443 | \ 444 | void greatest_do_fail(const char *name) { \ 445 | if (GREATEST_IS_VERBOSE()) { \ 446 | fprintf(GREATEST_STDOUT, \ 447 | "FAIL %s: %s (%s:%u)", \ 448 | name, greatest_info.msg ? greatest_info.msg : "", \ 449 | greatest_info.fail_file, greatest_info.fail_line); \ 450 | } else { \ 451 | fprintf(GREATEST_STDOUT, "F"); \ 452 | /* add linebreak if in line of '.'s */ \ 453 | if (greatest_info.col % greatest_info.width != 0) \ 454 | fprintf(GREATEST_STDOUT, "\n"); \ 455 | greatest_info.col = 0; \ 456 | fprintf(GREATEST_STDOUT, "FAIL %s: %s (%s:%u)\n", \ 457 | name, \ 458 | greatest_info.msg ? greatest_info.msg : "", \ 459 | greatest_info.fail_file, greatest_info.fail_line); \ 460 | } \ 461 | greatest_info.suite.failed++; \ 462 | } \ 463 | \ 464 | void greatest_do_skip(const char *name) { \ 465 | if (GREATEST_IS_VERBOSE()) { \ 466 | fprintf(GREATEST_STDOUT, "SKIP %s: %s", \ 467 | name, \ 468 | greatest_info.msg ? \ 469 | greatest_info.msg : "" ); \ 470 | } else { \ 471 | fprintf(GREATEST_STDOUT, "s"); \ 472 | } \ 473 | greatest_info.suite.skipped++; \ 474 | } \ 475 | \ 476 | void greatest_usage(const char *name) { \ 477 | fprintf(GREATEST_STDOUT, \ 478 | "Usage: %s [-hlfv] [-s SUITE] [-t TEST]\n" \ 479 | " -h print this Help\n" \ 480 | " -l List suites and their tests, then exit\n" \ 481 | " -f Stop runner after first failure\n" \ 482 | " -v Verbose output\n" \ 483 | " -s SUITE only run suite named SUITE\n" \ 484 | " -t TEST only run test named TEST\n", \ 485 | name); \ 486 | } \ 487 | \ 488 | void GREATEST_SET_SETUP_CB(greatest_setup_cb *cb, void *udata) { \ 489 | greatest_info.setup = cb; \ 490 | greatest_info.setup_udata = udata; \ 491 | } \ 492 | \ 493 | void GREATEST_SET_TEARDOWN_CB(greatest_teardown_cb *cb, \ 494 | void *udata) { \ 495 | greatest_info.teardown = cb; \ 496 | greatest_info.teardown_udata = udata; \ 497 | } \ 498 | \ 499 | greatest_run_info greatest_info 500 | 501 | /* Handle command-line arguments, etc. */ 502 | #define GREATEST_MAIN_BEGIN() \ 503 | do { \ 504 | int i = 0; \ 505 | memset(&greatest_info, 0, sizeof(greatest_info)); \ 506 | if (greatest_info.width == 0) { \ 507 | greatest_info.width = GREATEST_DEFAULT_WIDTH; \ 508 | } \ 509 | for (i = 1; i < argc; i++) { \ 510 | if (0 == strcmp("-t", argv[i])) { \ 511 | if (argc <= i + 1) { \ 512 | greatest_usage(argv[0]); \ 513 | exit(EXIT_FAILURE); \ 514 | } \ 515 | greatest_info.test_filter = argv[i+1]; \ 516 | i++; \ 517 | } else if (0 == strcmp("-s", argv[i])) { \ 518 | if (argc <= i + 1) { \ 519 | greatest_usage(argv[0]); \ 520 | exit(EXIT_FAILURE); \ 521 | } \ 522 | greatest_info.suite_filter = argv[i+1]; \ 523 | i++; \ 524 | } else if (0 == strcmp("-f", argv[i])) { \ 525 | greatest_info.flags |= GREATEST_FLAG_FIRST_FAIL; \ 526 | } else if (0 == strcmp("-v", argv[i])) { \ 527 | greatest_info.flags |= GREATEST_FLAG_VERBOSE; \ 528 | } else if (0 == strcmp("-l", argv[i])) { \ 529 | greatest_info.flags |= GREATEST_FLAG_LIST_ONLY; \ 530 | } else if (0 == strcmp("-h", argv[i])) { \ 531 | greatest_usage(argv[0]); \ 532 | exit(EXIT_SUCCESS); \ 533 | } else { \ 534 | fprintf(GREATEST_STDOUT, \ 535 | "Unknown argument '%s'\n", argv[i]); \ 536 | greatest_usage(argv[0]); \ 537 | exit(EXIT_FAILURE); \ 538 | } \ 539 | } \ 540 | } while (0); \ 541 | GREATEST_SET_TIME(greatest_info.begin) 542 | 543 | #define GREATEST_MAIN_END() \ 544 | do { \ 545 | if (!GREATEST_LIST_ONLY()) { \ 546 | GREATEST_SET_TIME(greatest_info.end); \ 547 | fprintf(GREATEST_STDOUT, \ 548 | "\nTotal: %u tests", greatest_info.tests_run); \ 549 | GREATEST_CLOCK_DIFF(greatest_info.begin, \ 550 | greatest_info.end); \ 551 | fprintf(GREATEST_STDOUT, "\n"); \ 552 | fprintf(GREATEST_STDOUT, \ 553 | "Pass: %u, fail: %u, skip: %u.\n", \ 554 | greatest_info.passed, \ 555 | greatest_info.failed, greatest_info.skipped); \ 556 | } \ 557 | return (greatest_info.failed > 0 \ 558 | ? EXIT_FAILURE : EXIT_SUCCESS); \ 559 | } while (0) 560 | 561 | /* Make abbreviations without the GREATEST_ prefix for the 562 | * most commonly used symbols. */ 563 | #if GREATEST_USE_ABBREVS 564 | #define TEST GREATEST_TEST 565 | #define SUITE GREATEST_SUITE 566 | #define RUN_TEST GREATEST_RUN_TEST 567 | #define RUN_TEST1 GREATEST_RUN_TEST1 568 | #define RUN_SUITE GREATEST_RUN_SUITE 569 | #define ASSERT GREATEST_ASSERT 570 | #define ASSERTm GREATEST_ASSERTm 571 | #define ASSERT_FALSE GREATEST_ASSERT_FALSE 572 | #define ASSERT_EQ GREATEST_ASSERT_EQ 573 | #define ASSERT_STR_EQ GREATEST_ASSERT_STR_EQ 574 | #define ASSERT_FALSEm GREATEST_ASSERT_FALSEm 575 | #define ASSERT_EQm GREATEST_ASSERT_EQm 576 | #define ASSERT_STR_EQm GREATEST_ASSERT_STR_EQm 577 | #define PASS GREATEST_PASS 578 | #define FAIL GREATEST_FAIL 579 | #define SKIP GREATEST_SKIP 580 | #define PASSm GREATEST_PASSm 581 | #define FAILm GREATEST_FAILm 582 | #define SKIPm GREATEST_SKIPm 583 | #define SET_SETUP GREATEST_SET_SETUP_CB 584 | #define SET_TEARDOWN GREATEST_SET_TEARDOWN_CB 585 | 586 | #if __STDC_VERSION__ >= 19901L 587 | #endif /* C99 */ 588 | #define RUN_TESTp GREATEST_RUN_TESTp 589 | #endif /* USE_ABBREVS */ 590 | 591 | #endif 592 | -------------------------------------------------------------------------------- /tests/test1.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | RETVAL=0 4 | 5 | PACFILE="1.js" 6 | 7 | . ./test_helper 8 | 9 | test_proxy $PACFILE http://abcdomain.com abcdomain.com "Found proxy DIRECT" 10 | test_proxy $PACFILE ftp://mydomain.com/x/ mydomain.com "Found proxy DIRECT" 11 | test_proxy $PACFILE http://a.local/x/ a.local "Found proxy DIRECT" 12 | test_proxy $PACFILE http://10.1.2.3/ 10.1.2.3 "Found proxy DIRECT" 13 | test_proxy $PACFILE http://172.16.1.2/x/ 172.16.1.2 "Found proxy DIRECT" 14 | test_proxy $PACFILE http://192.168.1.2/x/ 192.168.1.2 "Found proxy DIRECT" 15 | test_proxy $PACFILE http://127.0.0.5/x/ 127.0.0.5 "Found proxy DIRECT" 16 | test_proxy $PACFILE http://google.com/x google.com "Found proxy PROXY 4.5.6.7:8080; PROXY 7.8.9.10:8080" 17 | 18 | exit $RETVAL 19 | -------------------------------------------------------------------------------- /tests/test2.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | RETVAL=0 4 | 5 | PACFILE="2.js" 6 | 7 | . ./test_helper 8 | 9 | test_proxy $PACFILE http://*.*.ebscohost.com/x *.*.ebscohost.com "Found proxy PROXY proxylib.ntou.edu.tw:3128" 10 | test_proxy $PACFILE http://*.ebsco-content.com/x *.ebsco-content.com "Found proxy PROXY proxylib.ntou.edu.tw:3128" 11 | test_proxy $PACFILE http://129.35.213.31/x 129.35.213.31 "Found proxy PROXY proxylib.ntou.edu.tw:3128" 12 | test_proxy $PACFILE http://129.35.248.48/x 129.35.248.48 "Found proxy PROXY proxylib.ntou.edu.tw:3128" 13 | test_proxy $PACFILE http://134.243.85.3/x 134.243.85.3 "Found proxy PROXY proxylib.ntou.edu.tw:3128" 14 | test_proxy $PACFILE http://134.243.85.4/x 134.243.85.4 "Found proxy PROXY proxylib.ntou.edu.tw:3128" 15 | test_proxy $PACFILE http://140.121.140.100/x 140.121.140.100 "Found proxy PROXY proxylib.ntou.edu.tw:3128" 16 | test_proxy $PACFILE http://140.121.140.102/x 140.121.140.102 "Found proxy PROXY proxylib.ntou.edu.tw:3128" 17 | test_proxy $PACFILE http://140.121.140.103/x 140.121.140.103 "Found proxy PROXY proxylib.ntou.edu.tw:3128" 18 | test_proxy $PACFILE http://140.121.180.109/x 140.121.180.109 "Found proxy PROXY proxylib.ntou.edu.tw:3128" 19 | test_proxy $PACFILE http://156.csis.com.tw/x 156.csis.com.tw "Found proxy PROXY proxylib.ntou.edu.tw:3128" 20 | test_proxy $PACFILE http://165.193.122./x 165.193.122. "Found proxy PROXY proxylib.ntou.edu.tw:3128" 21 | test_proxy $PACFILE http://165.193.141./x 165.193.141. "Found proxy PROXY proxylib.ntou.edu.tw:3128" 22 | test_proxy $PACFILE http://167.216.170./x 167.216.170. "Found proxy PROXY proxylib.ntou.edu.tw:3128" 23 | test_proxy $PACFILE http://167.216.171./x 167.216.171. "Found proxy PROXY proxylib.ntou.edu.tw:3128" 24 | test_proxy $PACFILE http://170.225.184.106/x 170.225.184.106 "Found proxy PROXY proxylib.ntou.edu.tw:3128" 25 | test_proxy $PACFILE http://170.225.184.107/x 170.225.184.107 "Found proxy PROXY proxylib.ntou.edu.tw:3128" 26 | test_proxy $PACFILE http://170.225.96.21/x 170.225.96.21 "Found proxy PROXY proxylib.ntou.edu.tw:3128" 27 | test_proxy $PACFILE http://170.225.99.9/x 170.225.99.9 "Found proxy PROXY proxylib.ntou.edu.tw:3128" 28 | test_proxy $PACFILE http://192.83.186.103/x 192.83.186.103 "Found proxy PROXY proxylib.ntou.edu.tw:3128" 29 | test_proxy $PACFILE http://192.83.186.70/x 192.83.186.70 "Found proxy PROXY proxylib.ntou.edu.tw:3128" 30 | test_proxy $PACFILE http://192.83.186.71/x 192.83.186.71 "Found proxy PROXY proxylib.ntou.edu.tw:3128" 31 | test_proxy $PACFILE http://192.83.186.72/x 192.83.186.72 "Found proxy PROXY proxylib.ntou.edu.tw:3128" 32 | test_proxy $PACFILE http://192.83.186.84/x 192.83.186.84 "Found proxy PROXY proxylib.ntou.edu.tw:3128" 33 | test_proxy $PACFILE http://199.4.154./x 199.4.154. "Found proxy PROXY proxylib.ntou.edu.tw:3128" 34 | test_proxy $PACFILE http://199.4.155./x 199.4.155. "Found proxy PROXY proxylib.ntou.edu.tw:3128" 35 | test_proxy $PACFILE http://202.70.173.2/x 202.70.173.2 "Found proxy PROXY proxylib.ntou.edu.tw:3128" 36 | test_proxy $PACFILE http://203.70.208.88/x 203.70.208.88 "Found proxy PROXY proxylib.ntou.edu.tw:3128" 37 | test_proxy $PACFILE http://203.74.36.75/x 203.74.36.75 "Found proxy PROXY proxylib.ntou.edu.tw:3128" 38 | test_proxy $PACFILE http://205.240.244./x 205.240.244. "Found proxy PROXY proxylib.ntou.edu.tw:3128" 39 | test_proxy $PACFILE http://205.240.245./x 205.240.245. "Found proxy PROXY proxylib.ntou.edu.tw:3128" 40 | test_proxy $PACFILE http://205.240.246./x 205.240.246. "Found proxy PROXY proxylib.ntou.edu.tw:3128" 41 | test_proxy $PACFILE http://205.240.247./x 205.240.247. "Found proxy PROXY proxylib.ntou.edu.tw:3128" 42 | test_proxy $PACFILE http://205.243.231./x 205.243.231. "Found proxy PROXY proxylib.ntou.edu.tw:3128" 43 | test_proxy $PACFILE http://210.243.166.93/x 210.243.166.93 "Found proxy PROXY proxylib.ntou.edu.tw:3128" 44 | test_proxy $PACFILE http://211.20.182.42/x 211.20.182.42 "Found proxy PROXY proxylib.ntou.edu.tw:3128" 45 | test_proxy $PACFILE http://211.79.206.2/x 211.79.206.2 "Found proxy PROXY proxylib.ntou.edu.tw:3128" 46 | test_proxy $PACFILE http://211.79.206.4/x 211.79.206.4 "Found proxy PROXY proxylib.ntou.edu.tw:3128" 47 | test_proxy $PACFILE http://211.79.506.4/x 211.79.506.4 "Found proxy PROXY proxylib.ntou.edu.tw:3128" 48 | test_proxy $PACFILE http://220.228.59.156/x 220.228.59.156 "Found proxy PROXY proxylib.ntou.edu.tw:3128" 49 | test_proxy $PACFILE http://63.240.105./x 63.240.105. "Found proxy PROXY proxylib.ntou.edu.tw:3128" 50 | test_proxy $PACFILE http://63.240.113./x 63.240.113. "Found proxy PROXY proxylib.ntou.edu.tw:3128" 51 | test_proxy $PACFILE http://63.84.162./x 63.84.162. "Found proxy PROXY proxylib.ntou.edu.tw:3128" 52 | test_proxy $PACFILE http://63.86.118./x 63.86.118. "Found proxy PROXY proxylib.ntou.edu.tw:3128" 53 | test_proxy $PACFILE http://63.86.119./x 63.86.119. "Found proxy PROXY proxylib.ntou.edu.tw:3128" 54 | test_proxy $PACFILE http://65.246.184./x 65.246.184. "Found proxy PROXY proxylib.ntou.edu.tw:3128" 55 | test_proxy $PACFILE http://65.246.185./x 65.246.185. "Found proxy PROXY proxylib.ntou.edu.tw:3128" 56 | test_proxy $PACFILE http://aac.asm.org/x aac.asm.org "Found proxy PROXY proxylib.ntou.edu.tw:3128" 57 | test_proxy $PACFILE http://ac.els-cdn.com/x ac.els-cdn.com "Found proxy PROXY proxylib.ntou.edu.tw:3128" 58 | test_proxy $PACFILE http://admin-apps.webofknowledge.com/x admin-apps.webofknowledge.com "Found proxy PROXY proxylib.ntou.edu.tw:3128" 59 | test_proxy $PACFILE http://admin-router.webofknowledge.com/x admin-router.webofknowledge.com "Found proxy PROXY proxylib.ntou.edu.tw:3128" 60 | test_proxy $PACFILE http://admin.webofknowledge.com/x admin.webofknowledge.com "Found proxy PROXY proxylib.ntou.edu.tw:3128" 61 | test_proxy $PACFILE http://aem.asm.org/x aem.asm.org "Found proxy PROXY proxylib.ntou.edu.tw:3128" 62 | test_proxy $PACFILE http://afraf.oupjournals.org/x afraf.oupjournals.org "Found proxy PROXY proxylib.ntou.edu.tw:3128" 63 | test_proxy $PACFILE http://ageing.oupjournals.org/x ageing.oupjournals.org "Found proxy PROXY proxylib.ntou.edu.tw:3128" 64 | test_proxy $PACFILE http://aje.oupjournals.org/x aje.oupjournals.org "Found proxy PROXY proxylib.ntou.edu.tw:3128" 65 | test_proxy $PACFILE http://alcalc.oupjournals.org/x alcalc.oupjournals.org "Found proxy PROXY proxylib.ntou.edu.tw:3128" 66 | test_proxy $PACFILE http://aler.oupjournals.org/x aler.oupjournals.org "Found proxy PROXY proxylib.ntou.edu.tw:3128" 67 | test_proxy $PACFILE http://annhyg.oupjournals.org/x annhyg.oupjournals.org "Found proxy PROXY proxylib.ntou.edu.tw:3128" 68 | test_proxy $PACFILE http://annonc.oupjournals.org/x annonc.oupjournals.org "Found proxy PROXY proxylib.ntou.edu.tw:3128" 69 | test_proxy $PACFILE http://antonio.ingentaselect.com/x antonio.ingentaselect.com "Found proxy PROXY proxylib.ntou.edu.tw:3128" 70 | test_proxy $PACFILE http://ao.osa.org/x ao.osa.org "Found proxy PROXY proxylib.ntou.edu.tw:3128" 71 | test_proxy $PACFILE http://aob.oupjournals.org/x aob.oupjournals.org "Found proxy PROXY proxylib.ntou.edu.tw:3128" 72 | test_proxy $PACFILE http://aoip.osa.org/x aoip.osa.org "Found proxy PROXY proxylib.ntou.edu.tw:3128" 73 | test_proxy $PACFILE http://aolp.osa.org/x aolp.osa.org "Found proxy PROXY proxylib.ntou.edu.tw:3128" 74 | test_proxy $PACFILE http://aoot.osa.org/x aoot.osa.org "Found proxy PROXY proxylib.ntou.edu.tw:3128" 75 | test_proxy $PACFILE http://ap.ejournal.ascc.net/x ap.ejournal.ascc.net "Found proxy PROXY proxylib.ntou.edu.tw:3128" 76 | test_proxy $PACFILE http://apl.aip.org/x apl.aip.org "Found proxy PROXY proxylib.ntou.edu.tw:3128" 77 | test_proxy $PACFILE http://apollo.sinica.edu.tw/x apollo.sinica.edu.tw "Found proxy PROXY proxylib.ntou.edu.tw:3128" 78 | test_proxy $PACFILE http://apps.webofknowledge.com/x apps.webofknowledge.com "Found proxy PROXY proxylib.ntou.edu.tw:3128" 79 | test_proxy $PACFILE http://apps.webofknowledgev4.com/x apps.webofknowledgev4.com "Found proxy PROXY proxylib.ntou.edu.tw:3128" 80 | test_proxy $PACFILE http://arjournals.annualreviews.org/x arjournals.annualreviews.org "Found proxy PROXY proxylib.ntou.edu.tw:3128" 81 | test_proxy $PACFILE http://ascelibrary.aip.org/x ascelibrary.aip.org "Found proxy PROXY proxylib.ntou.edu.tw:3128" 82 | test_proxy $PACFILE http://atoz.ebsco.com/x atoz.ebsco.com "Found proxy PROXY proxylib.ntou.edu.tw:3128" 83 | test_proxy $PACFILE http://beck-online.beck.de/x beck-online.beck.de "Found proxy PROXY proxylib.ntou.edu.tw:3128" 84 | test_proxy $PACFILE http://beheco.oupjournals.org/x beheco.oupjournals.org "Found proxy PROXY proxylib.ntou.edu.tw:3128" 85 | test_proxy $PACFILE http://bencao.infolinker.com.tw/x bencao.infolinker.com.tw "Found proxy PROXY proxylib.ntou.edu.tw:3128" 86 | test_proxy $PACFILE http://big5.oversea.cnki.net/x big5.oversea.cnki.net "Found proxy PROXY proxylib.ntou.edu.tw:3128" 87 | test_proxy $PACFILE http://bioinformatics.oupjournals.org/x bioinformatics.oupjournals.org "Found proxy PROXY proxylib.ntou.edu.tw:3128" 88 | test_proxy $PACFILE http://biostatistics.oupjournals.org/x biostatistics.oupjournals.org "Found proxy PROXY proxylib.ntou.edu.tw:3128" 89 | test_proxy $PACFILE http://bizboard.nikkeibp.co.jp/x bizboard.nikkeibp.co.jp "Found proxy PROXY proxylib.ntou.edu.tw:3128" 90 | test_proxy $PACFILE http://bizboard.nikkeibp.co.jp/daigaku/x bizboard.nikkeibp.co.jp/daigaku "Found proxy PROXY proxylib.ntou.edu.tw:3128" 91 | test_proxy $PACFILE http://bja.oupjournals.org/x bja.oupjournals.org "Found proxy PROXY proxylib.ntou.edu.tw:3128" 92 | test_proxy $PACFILE http://bjc.oupjournals.org/x bjc.oupjournals.org "Found proxy PROXY proxylib.ntou.edu.tw:3128" 93 | test_proxy $PACFILE http://bjsw.oupjournals.org/x bjsw.oupjournals.org "Found proxy PROXY proxylib.ntou.edu.tw:3128" 94 | test_proxy $PACFILE http://bmb.oupjournals.org/x bmb.oupjournals.org "Found proxy PROXY proxylib.ntou.edu.tw:3128" 95 | test_proxy $PACFILE http://bmf.aip.org/x bmf.aip.org "Found proxy PROXY proxylib.ntou.edu.tw:3128" 96 | test_proxy $PACFILE http://brain.oupjournals.org/x brain.oupjournals.org "Found proxy PROXY proxylib.ntou.edu.tw:3128" 97 | test_proxy $PACFILE http://brief-treatment.oupjournals.org/x brief-treatment.oupjournals.org "Found proxy PROXY proxylib.ntou.edu.tw:3128" 98 | test_proxy $PACFILE http://carcin.oupjournals.org/x carcin.oupjournals.org "Found proxy PROXY proxylib.ntou.edu.tw:3128" 99 | test_proxy $PACFILE http://cco.cambridge.org/x cco.cambridge.org "Found proxy PROXY proxylib.ntou.edu.tw:3128" 100 | test_proxy $PACFILE http://cdj.oupjournals.org/x cdj.oupjournals.org "Found proxy PROXY proxylib.ntou.edu.tw:3128" 101 | test_proxy $PACFILE http://cdli.asm.org/x cdli.asm.org "Found proxy PROXY proxylib.ntou.edu.tw:3128" 102 | test_proxy $PACFILE http://cds1.webofknowledge.com/x cds1.webofknowledge.com "Found proxy PROXY proxylib.ntou.edu.tw:3128" 103 | test_proxy $PACFILE http://cds2.webofknowledge.com/x cds2.webofknowledge.com "Found proxy PROXY proxylib.ntou.edu.tw:3128" 104 | test_proxy $PACFILE http://cec.lib.apabi.com/x cec.lib.apabi.com "Found proxy PROXY proxylib.ntou.edu.tw:3128" 105 | test_proxy $PACFILE http://cep.oupjournals.org/x cep.oupjournals.org "Found proxy PROXY proxylib.ntou.edu.tw:3128" 106 | test_proxy $PACFILE http://cercor.oupjournals.org/x cercor.oupjournals.org "Found proxy PROXY proxylib.ntou.edu.tw:3128" 107 | test_proxy $PACFILE http://chaos.aip.org/x chaos.aip.org "Found proxy PROXY proxylib.ntou.edu.tw:3128" 108 | test_proxy $PACFILE http://charts.webofknowledge.com/x charts.webofknowledge.com "Found proxy PROXY proxylib.ntou.edu.tw:3128" 109 | test_proxy $PACFILE http://chemse.oupjournals.org/x chemse.oupjournals.org "Found proxy PROXY proxylib.ntou.edu.tw:3128" 110 | test_proxy $PACFILE http://ci.nii.ac.jp/x ci.nii.ac.jp "Found proxy PROXY proxylib.ntou.edu.tw:3128" 111 | test_proxy $PACFILE http://cje.oupjournals.org/x cje.oupjournals.org "Found proxy PROXY proxylib.ntou.edu.tw:3128" 112 | test_proxy $PACFILE http://cjn.csis.com.tw/x cjn.csis.com.tw "Found proxy PROXY proxylib.ntou.edu.tw:3128" 113 | test_proxy $PACFILE http://clipsy.oupjournals.org/x clipsy.oupjournals.org "Found proxy PROXY proxylib.ntou.edu.tw:3128" 114 | test_proxy $PACFILE http://cm.webofknowledge.com/x cm.webofknowledge.com "Found proxy PROXY proxylib.ntou.edu.tw:3128" 115 | test_proxy $PACFILE http://cm.webofknowledgev4.com/x cm.webofknowledgev4.com "Found proxy PROXY proxylib.ntou.edu.tw:3128" 116 | test_proxy $PACFILE http://cmr.asm.org/x cmr.asm.org "Found proxy PROXY proxylib.ntou.edu.tw:3128" 117 | test_proxy $PACFILE http://cnki.csis.com.tw/x cnki.csis.com.tw "Found proxy PROXY proxylib.ntou.edu.tw:3128" 118 | test_proxy $PACFILE http://cnki50.csis.com.tw/x cnki50.csis.com.tw "Found proxy PROXY proxylib.ntou.edu.tw:3128" 119 | test_proxy $PACFILE http://collections.chadwyck.co.uk/x collections.chadwyck.co.uk "Found proxy PROXY proxylib.ntou.edu.tw:3128" 120 | test_proxy $PACFILE http://concert.wisenews.net.tw/x concert.wisenews.net.tw "Found proxy PROXY proxylib.ntou.edu.tw:3128" 121 | test_proxy $PACFILE http://content.ebscohost.com/x content.ebscohost.com "Found proxy PROXY proxylib.ntou.edu.tw:3128" 122 | test_proxy $PACFILE http://cornell.mirror.aps.org/x cornell.mirror.aps.org "Found proxy PROXY proxylib.ntou.edu.tw:3128" 123 | test_proxy $PACFILE http://cpe.oupjournals.org/x cpe.oupjournals.org "Found proxy PROXY proxylib.ntou.edu.tw:3128" 124 | test_proxy $PACFILE http://csa.e-lib.nctu.edu.tw/x csa.e-lib.nctu.edu.tw "Found proxy PROXY proxylib.ntou.edu.tw:3128" 125 | test_proxy $PACFILE http://ct.oupjournals.org/x ct.oupjournals.org "Found proxy PROXY proxylib.ntou.edu.tw:3128" 126 | test_proxy $PACFILE http://database.yomiuri.co.jp/x database.yomiuri.co.jp "Found proxy PROXY proxylib.ntou.edu.tw:3128" 127 | test_proxy $PACFILE http://db.lib.ntou.edu.tw/x db.lib.ntou.edu.tw "Found proxy PROXY proxylib.ntou.edu.tw:3128" 128 | test_proxy $PACFILE http://deafed.oupjournals.org/x deafed.oupjournals.org "Found proxy PROXY proxylib.ntou.edu.tw:3128" 129 | test_proxy $PACFILE http://delivery.acm.org/x delivery.acm.org "Found proxy PROXY proxylib.ntou.edu.tw:3128" 130 | test_proxy $PACFILE http://demomars.csis.com.tw/x demomars.csis.com.tw "Found proxy PROXY proxylib.ntou.edu.tw:3128" 131 | test_proxy $PACFILE http://diipcs.webofknowledge.com/x diipcs.webofknowledge.com "Found proxy PROXY proxylib.ntou.edu.tw:3128" 132 | test_proxy $PACFILE http://dlib.apabi.com/x dlib.apabi.com "Found proxy PROXY proxylib.ntou.edu.tw:3128" 133 | test_proxy $PACFILE http://download.springer.com/x download.springer.com "Found proxy PROXY proxylib.ntou.edu.tw:3128" 134 | test_proxy $PACFILE http://ea.grolier.com/x ea.grolier.com "Found proxy PROXY proxylib.ntou.edu.tw:3128" 135 | test_proxy $PACFILE http://earthinteractions.org/x earthinteractions.org "Found proxy PROXY proxylib.ntou.edu.tw:3128" 136 | test_proxy $PACFILE http://ebook01.koobe.com.tw/x ebook01.koobe.com.tw "Found proxy PROXY proxylib.ntou.edu.tw:3128" 137 | test_proxy $PACFILE http://ebooks.abc-clio.com/x ebooks.abc-clio.com "Found proxy PROXY proxylib.ntou.edu.tw:3128" 138 | test_proxy $PACFILE http://ebooks.kluweronline.com/x ebooks.kluweronline.com "Found proxy PROXY proxylib.ntou.edu.tw:3128" 139 | test_proxy $PACFILE http://ebooks.springerlink.com/x ebooks.springerlink.com "Found proxy PROXY proxylib.ntou.edu.tw:3128" 140 | test_proxy $PACFILE http://ebooks.windeal.com.tw/x ebooks.windeal.com.tw "Found proxy PROXY proxylib.ntou.edu.tw:3128" 141 | test_proxy $PACFILE http://ec.asm.org/x ec.asm.org "Found proxy PROXY proxylib.ntou.edu.tw:3128" 142 | test_proxy $PACFILE http://edo.tw/x edo.tw "Found proxy PROXY proxylib.ntou.edu.tw:3128" 143 | test_proxy $PACFILE http://edo.tw/ocp.aspx?subs_no=20063/x edo.tw/ocp.aspx?subs_no=20063 "Found proxy PROXY proxylib.ntou.edu.tw:3128" 144 | test_proxy $PACFILE http://eds.a.ebscohost.com/x eds.a.ebscohost.com "Found proxy PROXY proxylib.ntou.edu.tw:3128" 145 | test_proxy $PACFILE http://eds.b.ebscohost.com/x eds.b.ebscohost.com "Found proxy PROXY proxylib.ntou.edu.tw:3128" 146 | test_proxy $PACFILE http://eds.c.ebscohost.com/x eds.c.ebscohost.com "Found proxy PROXY proxylib.ntou.edu.tw:3128" 147 | test_proxy $PACFILE http://eds.d.ebscohost.com/x eds.d.ebscohost.com "Found proxy PROXY proxylib.ntou.edu.tw:3128" 148 | test_proxy $PACFILE http://eds.e.ebscohost.com/x eds.e.ebscohost.com "Found proxy PROXY proxylib.ntou.edu.tw:3128" 149 | test_proxy $PACFILE http://edu1.wordpedia.com/x edu1.wordpedia.com "Found proxy PROXY proxylib.ntou.edu.tw:3128" 150 | test_proxy $PACFILE http://eebo.chadwyck.com/x eebo.chadwyck.com "Found proxy PROXY proxylib.ntou.edu.tw:3128" 151 | test_proxy $PACFILE http://ei.e-lib.nctu.edu.tw/x ei.e-lib.nctu.edu.tw "Found proxy PROXY proxylib.ntou.edu.tw:3128" 152 | test_proxy $PACFILE http://ei.oupjournals.org/x ei.oupjournals.org "Found proxy PROXY proxylib.ntou.edu.tw:3128" 153 | test_proxy $PACFILE http://ei.stic.gov.tw/x ei.stic.gov.tw "Found proxy PROXY proxylib.ntou.edu.tw:3128" 154 | test_proxy $PACFILE http://ej.iop.org/x ej.iop.org "Found proxy PROXY proxylib.ntou.edu.tw:3128" 155 | test_proxy $PACFILE http://elearning.webenglish.tv/x elearning.webenglish.tv "Found proxy PROXY proxylib.ntou.edu.tw:3128" 156 | test_proxy $PACFILE http://elib.infolinker.com.tw/x elib.infolinker.com.tw "Found proxy PROXY proxylib.ntou.edu.tw:3128" 157 | test_proxy $PACFILE http://emboj.oupjournals.org/x emboj.oupjournals.org "Found proxy PROXY proxylib.ntou.edu.tw:3128" 158 | test_proxy $PACFILE http://engineer.windeal.com.tw/x engineer.windeal.com.tw "Found proxy PROXY proxylib.ntou.edu.tw:3128" 159 | test_proxy $PACFILE http://enterprise.astm.org/x enterprise.astm.org "Found proxy PROXY proxylib.ntou.edu.tw:3128" 160 | test_proxy $PACFILE http://epirev.oupjournals.org/x epirev.oupjournals.org "Found proxy PROXY proxylib.ntou.edu.tw:3128" 161 | test_proxy $PACFILE http://epubs.siam.org/x epubs.siam.org "Found proxy PROXY proxylib.ntou.edu.tw:3128" 162 | test_proxy $PACFILE http://erae.oupjournals.org/x erae.oupjournals.org "Found proxy PROXY proxylib.ntou.edu.tw:3128" 163 | test_proxy $PACFILE http://eric.lib.nccu.edu.tw/x eric.lib.nccu.edu.tw "Found proxy PROXY proxylib.ntou.edu.tw:3128" 164 | test_proxy $PACFILE http://es.oupjournals.org/x es.oupjournals.org "Found proxy PROXY proxylib.ntou.edu.tw:3128" 165 | test_proxy $PACFILE http://esi.webofknowledge.com/x esi.webofknowledge.com "Found proxy PROXY proxylib.ntou.edu.tw:3128" 166 | test_proxy $PACFILE http://esr.oupjournals.org/x esr.oupjournals.org "Found proxy PROXY proxylib.ntou.edu.tw:3128" 167 | test_proxy $PACFILE http://estipub.isiknowledge.com/x estipub.isiknowledge.com "Found proxy PROXY proxylib.ntou.edu.tw:3128" 168 | test_proxy $PACFILE http://ethesys.lib.ntou.edu.tw/x ethesys.lib.ntou.edu.tw "Found proxy PROXY proxylib.ntou.edu.tw:3128" 169 | test_proxy $PACFILE http://fampra.oupjournals.org/x fampra.oupjournals.org "Found proxy PROXY proxylib.ntou.edu.tw:3128" 170 | test_proxy $PACFILE http://g.wanfangdata.com.hk/x g.wanfangdata.com.hk "Found proxy PROXY proxylib.ntou.edu.tw:3128" 171 | test_proxy $PACFILE http://galenet.galegroup.com/x galenet.galegroup.com "Found proxy PROXY proxylib.ntou.edu.tw:3128" 172 | test_proxy $PACFILE http://gateway.webofknowledge.com/x gateway.webofknowledge.com "Found proxy PROXY proxylib.ntou.edu.tw:3128" 173 | test_proxy $PACFILE http://german2.nccu.edu.tw/x german2.nccu.edu.tw "Found proxy PROXY proxylib.ntou.edu.tw:3128" 174 | test_proxy $PACFILE http://global.ebsco-content.com/x global.ebsco-content.com "Found proxy PROXY proxylib.ntou.edu.tw:3128" 175 | test_proxy $PACFILE http://global.umi.com/x global.umi.com "Found proxy PROXY proxylib.ntou.edu.tw:3128" 176 | test_proxy $PACFILE http://globalbb.onesource.com/x globalbb.onesource.com "Found proxy PROXY proxylib.ntou.edu.tw:3128" 177 | test_proxy $PACFILE http://glycob.oupjournals.org/x glycob.oupjournals.org "Found proxy PROXY proxylib.ntou.edu.tw:3128" 178 | test_proxy $PACFILE http://gme.grolier.com/x gme.grolier.com "Found proxy PROXY proxylib.ntou.edu.tw:3128" 179 | test_proxy $PACFILE http://go-passport.grolier.com/x go-passport.grolier.com "Found proxy PROXY proxylib.ntou.edu.tw:3128" 180 | test_proxy $PACFILE http://go.galegroup.com/x go.galegroup.com "Found proxy PROXY proxylib.ntou.edu.tw:3128" 181 | test_proxy $PACFILE http://go.grolier.com/x go.grolier.com "Found proxy PROXY proxylib.ntou.edu.tw:3128" 182 | test_proxy $PACFILE http://go.westlawjapan.com/x go.westlawjapan.com "Found proxy PROXY proxylib.ntou.edu.tw:3128" 183 | test_proxy $PACFILE http://haworthpress.com/x haworthpress.com "Found proxy PROXY proxylib.ntou.edu.tw:3128" 184 | test_proxy $PACFILE http://hbrtwn.infolinker.com.tw/x hbrtwn.infolinker.com.tw "Found proxy PROXY proxylib.ntou.edu.tw:3128" 185 | test_proxy $PACFILE http://hcr.oupjournals.org/x hcr.oupjournals.org "Found proxy PROXY proxylib.ntou.edu.tw:3128" 186 | test_proxy $PACFILE http://hcr3.webofknowledge.com/x hcr3.webofknowledge.com "Found proxy PROXY proxylib.ntou.edu.tw:3128" 187 | test_proxy $PACFILE http://heapol.oupjournals.org/x heapol.oupjournals.org "Found proxy PROXY proxylib.ntou.edu.tw:3128" 188 | test_proxy $PACFILE http://heapro.oupjournals.org/x heapro.oupjournals.org "Found proxy PROXY proxylib.ntou.edu.tw:3128" 189 | test_proxy $PACFILE http://her.oupjournals.org/x her.oupjournals.org "Found proxy PROXY proxylib.ntou.edu.tw:3128" 190 | test_proxy $PACFILE http://hjournals.cambridge.org/x hjournals.cambridge.org "Found proxy PROXY proxylib.ntou.edu.tw:3128" 191 | test_proxy $PACFILE http://hk.wanfangdata.com/x hk.wanfangdata.com "Found proxy PROXY proxylib.ntou.edu.tw:3128" 192 | test_proxy $PACFILE http://hmg.oupjournals.org/x hmg.oupjournals.org "Found proxy PROXY proxylib.ntou.edu.tw:3128" 193 | test_proxy $PACFILE http://http://infotrac.galegroup.com/x http://infotrac.galegroup.com "Found proxy PROXY proxylib.ntou.edu.tw:3128" 194 | test_proxy $PACFILE http://humrep.oupjournals.org/x humrep.oupjournals.org "Found proxy PROXY proxylib.ntou.edu.tw:3128" 195 | test_proxy $PACFILE http://hunteq.com/x hunteq.com "Found proxy PROXY proxylib.ntou.edu.tw:3128" 196 | test_proxy $PACFILE http://huso.stpi.narl.org.tw/x huso.stpi.narl.org.tw "Found proxy PROXY proxylib.ntou.edu.tw:3128" 197 | test_proxy $PACFILE http://huso.stpi.org.tw/x huso.stpi.org.tw "Found proxy PROXY proxylib.ntou.edu.tw:3128" 198 | test_proxy $PACFILE http://hyweb.ebook.hyread.com.tw/x hyweb.ebook.hyread.com.tw "Found proxy PROXY proxylib.ntou.edu.tw:3128" 199 | test_proxy $PACFILE http://iai.asm.org/x iai.asm.org "Found proxy PROXY proxylib.ntou.edu.tw:3128" 200 | test_proxy $PACFILE http://icc.oupjournals.org/x icc.oupjournals.org "Found proxy PROXY proxylib.ntou.edu.tw:3128" 201 | test_proxy $PACFILE http://ieee.org/x ieee.org "Found proxy PROXY proxylib.ntou.edu.tw:3128" 202 | test_proxy $PACFILE http://igroup.ebrary.com/x igroup.ebrary.com "Found proxy PROXY proxylib.ntou.edu.tw:3128" 203 | test_proxy $PACFILE http://ije.oupjournals.org/x ije.oupjournals.org "Found proxy PROXY proxylib.ntou.edu.tw:3128" 204 | test_proxy $PACFILE http://ijpor.oupjournals.org/x ijpor.oupjournals.org "Found proxy PROXY proxylib.ntou.edu.tw:3128" 205 | test_proxy $PACFILE http://ilibrary.com.tw/x ilibrary.com.tw "Found proxy PROXY proxylib.ntou.edu.tw:3128" 206 | test_proxy $PACFILE http://imagebank.osa.org/x imagebank.osa.org "Found proxy PROXY proxylib.ntou.edu.tw:3128" 207 | test_proxy $PACFILE http://images.webofknowledge.com/x images.webofknowledge.com "Found proxy PROXY proxylib.ntou.edu.tw:3128" 208 | test_proxy $PACFILE http://infotrac.galegroup.com/x infotrac.galegroup.com "Found proxy PROXY proxylib.ntou.edu.tw:3128" 209 | test_proxy $PACFILE http://infoweb.newsbank.com/x infoweb.newsbank.com "Found proxy PROXY proxylib.ntou.edu.tw:3128" 210 | test_proxy $PACFILE http://international.westlaw.com/x international.westlaw.com "Found proxy PROXY proxylib.ntou.edu.tw:3128" 211 | test_proxy $PACFILE http://intimm.oupjournals.org/x intimm.oupjournals.org "Found proxy PROXY proxylib.ntou.edu.tw:3128" 212 | test_proxy $PACFILE http://intqhc.oupjournals.org/x intqhc.oupjournals.org "Found proxy PROXY proxylib.ntou.edu.tw:3128" 213 | test_proxy $PACFILE http://iopscience.iop.org/x iopscience.iop.org "Found proxy PROXY proxylib.ntou.edu.tw:3128" 214 | test_proxy $PACFILE http://iospress.metapress.com/x iospress.metapress.com "Found proxy PROXY proxylib.ntou.edu.tw:3128" 215 | test_proxy $PACFILE http://irap.oupjournals.org/x irap.oupjournals.org "Found proxy PROXY proxylib.ntou.edu.tw:3128" 216 | test_proxy $PACFILE http://isi4.isiknowledge.com/x isi4.isiknowledge.com "Found proxy PROXY proxylib.ntou.edu.tw:3128" 217 | test_proxy $PACFILE http://isiknowledge.com/x isiknowledge.com "Found proxy PROXY proxylib.ntou.edu.tw:3128" 218 | test_proxy $PACFILE http://jac.oupjournals.org/x jac.oupjournals.org "Found proxy PROXY proxylib.ntou.edu.tw:3128" 219 | test_proxy $PACFILE http://jae.oupjournals.org/x jae.oupjournals.org "Found proxy PROXY proxylib.ntou.edu.tw:3128" 220 | test_proxy $PACFILE http://jap.aip.org/x jap.aip.org "Found proxy PROXY proxylib.ntou.edu.tw:3128" 221 | test_proxy $PACFILE http://jb.asm.org/x jb.asm.org "Found proxy PROXY proxylib.ntou.edu.tw:3128" 222 | test_proxy $PACFILE http://jcm.asm.org/x jcm.asm.org "Found proxy PROXY proxylib.ntou.edu.tw:3128" 223 | test_proxy $PACFILE http://jcp.aip.org/x jcp.aip.org "Found proxy PROXY proxylib.ntou.edu.tw:3128" 224 | test_proxy $PACFILE http://jcr1.isiknowledge.com/x jcr1.isiknowledge.com "Found proxy PROXY proxylib.ntou.edu.tw:3128" 225 | test_proxy $PACFILE http://jeg.oupjournals.org/x jeg.oupjournals.org "Found proxy PROXY proxylib.ntou.edu.tw:3128" 226 | test_proxy $PACFILE http://jhered.oupjournals.org/x jhered.oupjournals.org "Found proxy PROXY proxylib.ntou.edu.tw:3128" 227 | test_proxy $PACFILE http://jjco.oupjournals.org/x jjco.oupjournals.org "Found proxy PROXY proxylib.ntou.edu.tw:3128" 228 | test_proxy $PACFILE http://jleo.oupjournals.org/x jleo.oupjournals.org "Found proxy PROXY proxylib.ntou.edu.tw:3128" 229 | test_proxy $PACFILE http://jlt.osa.org/x jlt.osa.org "Found proxy PROXY proxylib.ntou.edu.tw:3128" 230 | test_proxy $PACFILE http://jmicro.oupjournals.org/x jmicro.oupjournals.org "Found proxy PROXY proxylib.ntou.edu.tw:3128" 231 | test_proxy $PACFILE http://jmp.aip.org/x jmp.aip.org "Found proxy PROXY proxylib.ntou.edu.tw:3128" 232 | test_proxy $PACFILE http://jn.physiology.org/x jn.physiology.org "Found proxy PROXY proxylib.ntou.edu.tw:3128" 233 | test_proxy $PACFILE http://jncicancerspectrum.oupjournals.org/x jncicancerspectrum.oupjournals.org "Found proxy PROXY proxylib.ntou.edu.tw:3128" 234 | test_proxy $PACFILE http://joc.oupjournals.org/x joc.oupjournals.org "Found proxy PROXY proxylib.ntou.edu.tw:3128" 235 | test_proxy $PACFILE http://josaa.osa.org/x josaa.osa.org "Found proxy PROXY proxylib.ntou.edu.tw:3128" 236 | test_proxy $PACFILE http://jot.osa.org/x jot.osa.org "Found proxy PROXY proxylib.ntou.edu.tw:3128" 237 | test_proxy $PACFILE http://journals.ametsoc.org/x journals.ametsoc.org "Found proxy PROXY proxylib.ntou.edu.tw:3128" 238 | test_proxy $PACFILE http://journals.asm.org/x journals.asm.org "Found proxy PROXY proxylib.ntou.edu.tw:3128" 239 | test_proxy $PACFILE http://journals.cambridge.org/x journals.cambridge.org "Found proxy PROXY proxylib.ntou.edu.tw:3128" 240 | test_proxy $PACFILE http://journals.kluweronline.com/x journals.kluweronline.com "Found proxy PROXY proxylib.ntou.edu.tw:3128" 241 | test_proxy $PACFILE http://journals.wspc.com.sg/x journals.wspc.com.sg "Found proxy PROXY proxylib.ntou.edu.tw:3128" 242 | test_proxy $PACFILE http://jpart.oupjournals.org/x jpart.oupjournals.org "Found proxy PROXY proxylib.ntou.edu.tw:3128" 243 | test_proxy $PACFILE http://jpcrd.aip.org/x jpcrd.aip.org "Found proxy PROXY proxylib.ntou.edu.tw:3128" 244 | test_proxy $PACFILE http://jpepsy.oupjournals.org/x jpepsy.oupjournals.org "Found proxy PROXY proxylib.ntou.edu.tw:3128" 245 | test_proxy $PACFILE http://jrse.aip.org/x jrse.aip.org "Found proxy PROXY proxylib.ntou.edu.tw:3128" 246 | test_proxy $PACFILE http://jurban.oupjournals.org/x jurban.oupjournals.org "Found proxy PROXY proxylib.ntou.edu.tw:3128" 247 | test_proxy $PACFILE http://jvi.asm.org/x jvi.asm.org "Found proxy PROXY proxylib.ntou.edu.tw:3128" 248 | test_proxy $PACFILE http://jxb.oupjournals.org/x jxb.oupjournals.org "Found proxy PROXY proxylib.ntou.edu.tw:3128" 249 | test_proxy $PACFILE http://klassiker.chadwyck.co.uk/x klassiker.chadwyck.co.uk "Found proxy PROXY proxylib.ntou.edu.tw:3128" 250 | test_proxy $PACFILE http://kmw.ctgin.com/x kmw.ctgin.com "Found proxy PROXY proxylib.ntou.edu.tw:3128" 251 | test_proxy $PACFILE http://lang.ntou.edu.tw/source.php/x lang.ntou.edu.tw/source.php "Found proxy PROXY proxylib.ntou.edu.tw:3128" 252 | test_proxy $PACFILE http://lb20.ah100.libraryandbook.net/x lb20.ah100.libraryandbook.net "Found proxy PROXY proxylib.ntou.edu.tw:3128" 253 | test_proxy $PACFILE http://lb20.botw.libraryandbook.net/x lb20.botw.libraryandbook.net "Found proxy PROXY proxylib.ntou.edu.tw:3128" 254 | test_proxy $PACFILE http://lb20.dummies.libraryandbook.net/x lb20.dummies.libraryandbook.net "Found proxy PROXY proxylib.ntou.edu.tw:3128" 255 | test_proxy $PACFILE http://lb20.tabf.libraryandbook.net/x lb20.tabf.libraryandbook.net "Found proxy PROXY proxylib.ntou.edu.tw:3128" 256 | test_proxy $PACFILE http://legal.lexisnexis.jp/x legal.lexisnexis.jp "Found proxy PROXY proxylib.ntou.edu.tw:3128" 257 | test_proxy $PACFILE http://lib.myilibrary.com/x lib.myilibrary.com "Found proxy PROXY proxylib.ntou.edu.tw:3128" 258 | test_proxy $PACFILE http://library.books24x7.com/x library.books24x7.com "Found proxy PROXY proxylib.ntou.edu.tw:3128" 259 | test_proxy $PACFILE http://library.pressdisplay.com/x library.pressdisplay.com "Found proxy PROXY proxylib.ntou.edu.tw:3128" 260 | test_proxy $PACFILE http://link.aps.org/x link.aps.org "Found proxy PROXY proxylib.ntou.edu.tw:3128" 261 | test_proxy $PACFILE http://link.springer-ny.com/x link.springer-ny.com "Found proxy PROXY proxylib.ntou.edu.tw:3128" 262 | test_proxy $PACFILE http://link.springer.com/x link.springer.com "Found proxy PROXY proxylib.ntou.edu.tw:3128" 263 | test_proxy $PACFILE http://link.springer.de/x link.springer.de "Found proxy PROXY proxylib.ntou.edu.tw:3128" 264 | test_proxy $PACFILE http://links.springer.com/x links.springer.com "Found proxy PROXY proxylib.ntou.edu.tw:3128" 265 | test_proxy $PACFILE http://links.webofknowledge.com/x links.webofknowledge.com "Found proxy PROXY proxylib.ntou.edu.tw:3128" 266 | test_proxy $PACFILE http://ltp.aip.org/x ltp.aip.org "Found proxy PROXY proxylib.ntou.edu.tw:3128" 267 | test_proxy $PACFILE http://mars.csa.com/x mars.csa.com "Found proxy PROXY proxylib.ntou.edu.tw:3128" 268 | test_proxy $PACFILE http://mars.csis.com.tw/x mars.csis.com.tw "Found proxy PROXY proxylib.ntou.edu.tw:3128" 269 | test_proxy $PACFILE http://mars2.csa.com/x mars2.csa.com "Found proxy PROXY proxylib.ntou.edu.tw:3128" 270 | test_proxy $PACFILE http://mars3.csa.com/x mars3.csa.com "Found proxy PROXY proxylib.ntou.edu.tw:3128" 271 | test_proxy $PACFILE http://mbe.oupjournals.org/x mbe.oupjournals.org "Found proxy PROXY proxylib.ntou.edu.tw:3128" 272 | test_proxy $PACFILE http://mcb.asm.org/x mcb.asm.org "Found proxy PROXY proxylib.ntou.edu.tw:3128" 273 | test_proxy $PACFILE http://md1.csa.com/x md1.csa.com "Found proxy PROXY proxylib.ntou.edu.tw:3128" 274 | test_proxy $PACFILE http://md2.csa.com/x md2.csa.com "Found proxy PROXY proxylib.ntou.edu.tw:3128" 275 | test_proxy $PACFILE http://minghouse.infolinker.com.tw/x minghouse.infolinker.com.tw "Found proxy PROXY proxylib.ntou.edu.tw:3128" 276 | test_proxy $PACFILE http://mmbr.asm.org/x mmbr.asm.org "Found proxy PROXY proxylib.ntou.edu.tw:3128" 277 | test_proxy $PACFILE http://molehr.oupjournals.org/x molehr.oupjournals.org "Found proxy PROXY proxylib.ntou.edu.tw:3128" 278 | test_proxy $PACFILE http://mollus.oupjournals.org/x mollus.oupjournals.org "Found proxy PROXY proxylib.ntou.edu.tw:3128" 279 | test_proxy $PACFILE http://mutage.oupjournals.org/x mutage.oupjournals.org "Found proxy PROXY proxylib.ntou.edu.tw:3128" 280 | test_proxy $PACFILE http://mydigitallibrary.lib.overdrive.com/x mydigitallibrary.lib.overdrive.com "Found proxy PROXY proxylib.ntou.edu.tw:3128" 281 | test_proxy $PACFILE http://nar.oupjournals.org/x nar.oupjournals.org "Found proxy PROXY proxylib.ntou.edu.tw:3128" 282 | test_proxy $PACFILE http://ncl3web.hyweb.com.tw/x ncl3web.hyweb.com.tw "Found proxy PROXY proxylib.ntou.edu.tw:3128" 283 | test_proxy $PACFILE http://ndt.oupjournals.org/x ndt.oupjournals.org "Found proxy PROXY proxylib.ntou.edu.tw:3128" 284 | test_proxy $PACFILE http://new.cwk.com.tw/x new.cwk.com.tw "Found proxy PROXY proxylib.ntou.edu.tw:3128" 285 | test_proxy $PACFILE http://newfirstsearch.global.oclc.org/x newfirstsearch.global.oclc.org "Found proxy PROXY proxylib.ntou.edu.tw:3128" 286 | test_proxy $PACFILE http://newfirstsearch.oclc.org/x newfirstsearch.oclc.org "Found proxy PROXY proxylib.ntou.edu.tw:3128" 287 | test_proxy $PACFILE http://ntou.ebook.hyread.com.tw/x ntou.ebook.hyread.com.tw "Found proxy PROXY proxylib.ntou.edu.tw:3128" 288 | test_proxy $PACFILE http://ntou.koobe.com.tw/x ntou.koobe.com.tw "Found proxy PROXY proxylib.ntou.edu.tw:3128" 289 | test_proxy $PACFILE http://ntt1.hyweb.com.tw/x ntt1.hyweb.com.tw "Found proxy PROXY proxylib.ntou.edu.tw:3128" 290 | test_proxy $PACFILE http://occmed.oupjournals.org/x occmed.oupjournals.org "Found proxy PROXY proxylib.ntou.edu.tw:3128" 291 | test_proxy $PACFILE http://oep.oupjournals.org/x oep.oupjournals.org "Found proxy PROXY proxylib.ntou.edu.tw:3128" 292 | test_proxy $PACFILE http://oh1.csa.com/x oh1.csa.com "Found proxy PROXY proxylib.ntou.edu.tw:3128" 293 | test_proxy $PACFILE http://oh2.csa.com/x oh2.csa.com "Found proxy PROXY proxylib.ntou.edu.tw:3128" 294 | test_proxy $PACFILE http://ojps.aip.org/x ojps.aip.org "Found proxy PROXY proxylib.ntou.edu.tw:3128" 295 | test_proxy $PACFILE http://ol.osa.org/x ol.osa.org "Found proxy PROXY proxylib.ntou.edu.tw:3128" 296 | test_proxy $PACFILE http://oldweb.cqvip.com/x oldweb.cqvip.com "Found proxy PROXY proxylib.ntou.edu.tw:3128" 297 | test_proxy $PACFILE http://omed.nuazure.info/x omed.nuazure.info "Found proxy PROXY proxylib.ntou.edu.tw:3128" 298 | test_proxy $PACFILE http://online.sagepub.com/x online.sagepub.com "Found proxy PROXY proxylib.ntou.edu.tw:3128" 299 | test_proxy $PACFILE http://onlinelibrary.wiley.com/x onlinelibrary.wiley.com "Found proxy PROXY proxylib.ntou.edu.tw:3128" 300 | test_proxy $PACFILE http://ortho.oupjournals.org/x ortho.oupjournals.org "Found proxy PROXY proxylib.ntou.edu.tw:3128" 301 | test_proxy $PACFILE http://oversea.cnki.net/x oversea.cnki.net "Found proxy PROXY proxylib.ntou.edu.tw:3128" 302 | test_proxy $PACFILE http://ovid.stic.gov.tw/x ovid.stic.gov.tw "Found proxy PROXY proxylib.ntou.edu.tw:3128" 303 | test_proxy $PACFILE http://ovidsp.ovid.com/x ovidsp.ovid.com "Found proxy PROXY proxylib.ntou.edu.tw:3128" 304 | test_proxy $PACFILE http://oxfordjournals.org/x oxfordjournals.org "Found proxy PROXY proxylib.ntou.edu.tw:3128" 305 | test_proxy $PACFILE http://oxrep.oupjournals.org/x oxrep.oupjournals.org "Found proxy PROXY proxylib.ntou.edu.tw:3128" 306 | test_proxy $PACFILE http://pa.oupjournals.org/x pa.oupjournals.org "Found proxy PROXY proxylib.ntou.edu.tw:3128" 307 | test_proxy $PACFILE http://pan.oupjournals.org/x pan.oupjournals.org "Found proxy PROXY proxylib.ntou.edu.tw:3128" 308 | test_proxy $PACFILE http://pao.chadwyck.co.uk/x pao.chadwyck.co.uk "Found proxy PROXY proxylib.ntou.edu.tw:3128" 309 | test_proxy $PACFILE http://pcp.oupjournals.org/x pcp.oupjournals.org "Found proxy PROXY proxylib.ntou.edu.tw:3128" 310 | test_proxy $PACFILE http://pcs.webofknowledge.com/x pcs.webofknowledge.com "Found proxy PROXY proxylib.ntou.edu.tw:3128" 311 | test_proxy $PACFILE http://pcs.webofknowledgev4com/x pcs.webofknowledgev4com "Found proxy PROXY proxylib.ntou.edu.tw:3128" 312 | test_proxy $PACFILE http://pdn.sciencedirect.com/x pdn.sciencedirect.com "Found proxy PROXY proxylib.ntou.edu.tw:3128" 313 | test_proxy $PACFILE http://petrology.oupjournals.org/x petrology.oupjournals.org "Found proxy PROXY proxylib.ntou.edu.tw:3128" 314 | test_proxy $PACFILE http://phr.oupjournals.org/x phr.oupjournals.org "Found proxy PROXY proxylib.ntou.edu.tw:3128" 315 | test_proxy $PACFILE http://physics.aps.org/x physics.aps.org "Found proxy PROXY proxylib.ntou.edu.tw:3128" 316 | test_proxy $PACFILE http://physiolgenomics.physiology.org/x physiolgenomics.physiology.org "Found proxy PROXY proxylib.ntou.edu.tw:3128" 317 | test_proxy $PACFILE http://plankt.oupjournals.org/x plankt.oupjournals.org "Found proxy PROXY proxylib.ntou.edu.tw:3128" 318 | test_proxy $PACFILE http://pm.nlx.com/x pm.nlx.com "Found proxy PROXY proxylib.ntou.edu.tw:3128" 319 | test_proxy $PACFILE http://pm.nlx.com/xtf/search?browse-collections=true/x pm.nlx.com/xtf/search?browse-collections=true "Found proxy PROXY proxylib.ntou.edu.tw:3128" 320 | test_proxy $PACFILE http://pof.aip.org/x pof.aip.org "Found proxy PROXY proxylib.ntou.edu.tw:3128" 321 | test_proxy $PACFILE http://pop.aip.org/x pop.aip.org "Found proxy PROXY proxylib.ntou.edu.tw:3128" 322 | test_proxy $PACFILE http://portal.acm.org/x portal.acm.org "Found proxy PROXY proxylib.ntou.edu.tw:3128" 323 | test_proxy $PACFILE http://portal.isiknowledge.com/x portal.isiknowledge.com "Found proxy PROXY proxylib.ntou.edu.tw:3128" 324 | test_proxy $PACFILE http://pqdd.sinica.edu.tw/x pqdd.sinica.edu.tw "Found proxy PROXY proxylib.ntou.edu.tw:3128" 325 | test_proxy $PACFILE http://pra.aps.org/x pra.aps.org "Found proxy PROXY proxylib.ntou.edu.tw:3128" 326 | test_proxy $PACFILE http://prb.aps.org/x prb.aps.org "Found proxy PROXY proxylib.ntou.edu.tw:3128" 327 | test_proxy $PACFILE http://prc.aps.org/x prc.aps.org "Found proxy PROXY proxylib.ntou.edu.tw:3128" 328 | test_proxy $PACFILE http://prd.aps.org/x prd.aps.org "Found proxy PROXY proxylib.ntou.edu.tw:3128" 329 | test_proxy $PACFILE http://pre.aps.org/x pre.aps.org "Found proxy PROXY proxylib.ntou.edu.tw:3128" 330 | test_proxy $PACFILE http://prl.aps.org/x prl.aps.org "Found proxy PROXY proxylib.ntou.edu.tw:3128" 331 | test_proxy $PACFILE http://pro-twfubao.infolinker.com.tw/x pro-twfubao.infolinker.com.tw "Found proxy PROXY proxylib.ntou.edu.tw:3128" 332 | test_proxy $PACFILE http://prola.aps.org/x prola.aps.org "Found proxy PROXY proxylib.ntou.edu.tw:3128" 333 | test_proxy $PACFILE http://prola.library.cornell.edu/x prola.library.cornell.edu "Found proxy PROXY proxylib.ntou.edu.tw:3128" 334 | test_proxy $PACFILE http://proquest.umi.com/x proquest.umi.com "Found proxy PROXY proxylib.ntou.edu.tw:3128" 335 | test_proxy $PACFILE http://proquest.uni.com/x proquest.uni.com "Found proxy PROXY proxylib.ntou.edu.tw:3128" 336 | test_proxy $PACFILE http://protein.oupjournals.org/x protein.oupjournals.org "Found proxy PROXY proxylib.ntou.edu.tw:3128" 337 | test_proxy $PACFILE http://ptr.oupjournals.org/x ptr.oupjournals.org "Found proxy PROXY proxylib.ntou.edu.tw:3128" 338 | test_proxy $PACFILE http://pubmed.oupjournals.org/x pubmed.oupjournals.org "Found proxy PROXY proxylib.ntou.edu.tw:3128" 339 | test_proxy $PACFILE http://pubs.acs.org/x pubs.acs.org "Found proxy PROXY proxylib.ntou.edu.tw:3128" 340 | test_proxy $PACFILE http://pubs.rsc.org/x pubs.rsc.org "Found proxy PROXY proxylib.ntou.edu.tw:3128" 341 | test_proxy $PACFILE http://pubs3.acs.org/x pubs3.acs.org "Found proxy PROXY proxylib.ntou.edu.tw:3128" 342 | test_proxy $PACFILE http://qjmed.oupjournals.org/x qjmed.oupjournals.org "Found proxy PROXY proxylib.ntou.edu.tw:3128" 343 | test_proxy $PACFILE http://reading.udn.com/x reading.udn.com "Found proxy PROXY proxylib.ntou.edu.tw:3128" 344 | test_proxy $PACFILE http://readopac.ncl.edu.tw/x readopac.ncl.edu.tw "Found proxy PROXY proxylib.ntou.edu.tw:3128" 345 | test_proxy $PACFILE http://readopac2.ncl.edu.tw/x readopac2.ncl.edu.tw "Found proxy PROXY proxylib.ntou.edu.tw:3128" 346 | test_proxy $PACFILE http://readopac3.ncl.edu.tw/x readopac3.ncl.edu.tw "Found proxy PROXY proxylib.ntou.edu.tw:3128" 347 | test_proxy $PACFILE http://reference.kluweronline.com/x reference.kluweronline.com "Found proxy PROXY proxylib.ntou.edu.tw:3128" 348 | test_proxy $PACFILE http://refworks.reference-global.com/x refworks.reference-global.com "Found proxy PROXY proxylib.ntou.edu.tw:3128" 349 | test_proxy $PACFILE http://rfs.oupjournals.org/x rfs.oupjournals.org "Found proxy PROXY proxylib.ntou.edu.tw:3128" 350 | test_proxy $PACFILE http://rheumatology.oupjournals.org/x rheumatology.oupjournals.org "Found proxy PROXY proxylib.ntou.edu.tw:3128" 351 | test_proxy $PACFILE http://rmp.aps.org/x rmp.aps.org "Found proxy PROXY proxylib.ntou.edu.tw:3128" 352 | test_proxy $PACFILE http://rsi.aip.org/x rsi.aip.org "Found proxy PROXY proxylib.ntou.edu.tw:3128" 353 | test_proxy $PACFILE http://rss.webofknowledge.com/x rss.webofknowledge.com "Found proxy PROXY proxylib.ntou.edu.tw:3128" 354 | test_proxy $PACFILE http://schiller.chadwyck.co.uk/x schiller.chadwyck.co.uk "Found proxy PROXY proxylib.ntou.edu.tw:3128" 355 | test_proxy $PACFILE http://sciencenow.sciencemag.org/x sciencenow.sciencemag.org "Found proxy PROXY proxylib.ntou.edu.tw:3128" 356 | test_proxy $PACFILE http://scifinder.cas.org/x scifinder.cas.org "Found proxy PROXY proxylib.ntou.edu.tw:3128" 357 | test_proxy $PACFILE http://scitation.aip.org/x scitation.aip.org "Found proxy PROXY proxylib.ntou.edu.tw:3128" 358 | test_proxy $PACFILE http://sdos.ejournal.ascc.net/x sdos.ejournal.ascc.net "Found proxy PROXY proxylib.ntou.edu.tw:3128" 359 | test_proxy $PACFILE http://search.ebscohost.com/x search.ebscohost.com "Found proxy PROXY proxylib.ntou.edu.tw:3128" 360 | test_proxy $PACFILE http://search.epnet.com/x search.epnet.com "Found proxy PROXY proxylib.ntou.edu.tw:3128" 361 | test_proxy $PACFILE http://search.isiknowledge.com/x search.isiknowledge.com "Found proxy PROXY proxylib.ntou.edu.tw:3128" 362 | test_proxy $PACFILE http://search.proquest.com/x search.proquest.com "Found proxy PROXY proxylib.ntou.edu.tw:3128" 363 | test_proxy $PACFILE http://search.webofknowledge.com/x search.webofknowledge.com "Found proxy PROXY proxylib.ntou.edu.tw:3128" 364 | test_proxy $PACFILE http://ser.oupjournals.org/x ser.oupjournals.org "Found proxy PROXY proxylib.ntou.edu.tw:3128" 365 | test_proxy $PACFILE http://service.csa.com.tw/x service.csa.com.tw "Found proxy PROXY proxylib.ntou.edu.tw:3128" 366 | test_proxy $PACFILE http://service.flysheet.com.tw/x service.flysheet.com.tw "Found proxy PROXY proxylib.ntou.edu.tw:3128" 367 | test_proxy $PACFILE http://service.refworks.com.tw/x service.refworks.com.tw "Found proxy PROXY proxylib.ntou.edu.tw:3128" 368 | test_proxy $PACFILE http://shmu.alexanderstreet.com/x shmu.alexanderstreet.com "Found proxy PROXY proxylib.ntou.edu.tw:3128" 369 | test_proxy $PACFILE http://site.ebrary.com/x site.ebrary.com "Found proxy PROXY proxylib.ntou.edu.tw:3128" 370 | test_proxy $PACFILE http://soth.alexanderstreet.com/x soth.alexanderstreet.com "Found proxy PROXY proxylib.ntou.edu.tw:3128" 371 | test_proxy $PACFILE http://sp.oupjournals.org/x sp.oupjournals.org "Found proxy PROXY proxylib.ntou.edu.tw:3128" 372 | test_proxy $PACFILE http://springerlink.metapress.com/x springerlink.metapress.com "Found proxy PROXY proxylib.ntou.edu.tw:3128" 373 | test_proxy $PACFILE http://ssjj.oupjournals.org/x ssjj.oupjournals.org "Found proxy PROXY proxylib.ntou.edu.tw:3128" 374 | test_proxy $PACFILE http://stfb.ntl.edu.tw/x stfb.ntl.edu.tw "Found proxy PROXY proxylib.ntou.edu.tw:3128" 375 | test_proxy $PACFILE http://stfj.ntl.edu.tw/x stfj.ntl.edu.tw "Found proxy PROXY proxylib.ntou.edu.tw:3128" 376 | test_proxy $PACFILE http://sub3.webofknowledge.com/x sub3.webofknowledge.com "Found proxy PROXY proxylib.ntou.edu.tw:3128" 377 | test_proxy $PACFILE http://survival.oupjournals.org/x survival.oupjournals.org "Found proxy PROXY proxylib.ntou.edu.tw:3128" 378 | test_proxy $PACFILE http://sushi.webofknowledge.com/x sushi.webofknowledge.com "Found proxy PROXY proxylib.ntou.edu.tw:3128" 379 | test_proxy $PACFILE http://swproxy.swetswise.com/x swproxy.swetswise.com "Found proxy PROXY proxylib.ntou.edu.tw:3128" 380 | test_proxy $PACFILE http://taebc.ebook.hyread.com.tw/x taebc.ebook.hyread.com.tw "Found proxy PROXY proxylib.ntou.edu.tw:3128" 381 | test_proxy $PACFILE http://taebc.etailer.dpsl.net/x taebc.etailer.dpsl.net "Found proxy PROXY proxylib.ntou.edu.tw:3128" 382 | test_proxy $PACFILE http://taebc.koobe.com.tw/x taebc.koobe.com.tw "Found proxy PROXY proxylib.ntou.edu.tw:3128" 383 | test_proxy $PACFILE http://taebcmgh.sa.libraryandbook.net/x taebcmgh.sa.libraryandbook.net "Found proxy PROXY proxylib.ntou.edu.tw:3128" 384 | test_proxy $PACFILE http://tandf.msgfocus.com/x tandf.msgfocus.com "Found proxy PROXY proxylib.ntou.edu.tw:3128" 385 | test_proxy $PACFILE http://tao.wordpedia.com/x tao.wordpedia.com "Found proxy PROXY proxylib.ntou.edu.tw:3128" 386 | test_proxy $PACFILE http://tbmcdb.infolinker.com.tw/x tbmcdb.infolinker.com.tw "Found proxy PROXY proxylib.ntou.edu.tw:3128" 387 | test_proxy $PACFILE http://tcsd.lib.ntu.edu.tw/x tcsd.lib.ntu.edu.tw "Found proxy PROXY proxylib.ntou.edu.tw:3128" 388 | test_proxy $PACFILE http://tebko.infolinker.com.tw/x tebko.infolinker.com.tw "Found proxy PROXY proxylib.ntou.edu.tw:3128" 389 | test_proxy $PACFILE http://tie.tier.org.tw/x tie.tier.org.tw "Found proxy PROXY proxylib.ntou.edu.tw:3128" 390 | test_proxy $PACFILE http://toc.webofknowledge.com/x toc.webofknowledge.com "Found proxy PROXY proxylib.ntou.edu.tw:3128" 391 | test_proxy $PACFILE http://toc.webofknowledgev4.com/x toc.webofknowledgev4.com "Found proxy PROXY proxylib.ntou.edu.tw:3128" 392 | test_proxy $PACFILE http://tongji.oversea.cnki.net/x tongji.oversea.cnki.net "Found proxy PROXY proxylib.ntou.edu.tw:3128" 393 | test_proxy $PACFILE http://toxsci.oupjournals.org/x toxsci.oupjournals.org "Found proxy PROXY proxylib.ntou.edu.tw:3128" 394 | test_proxy $PACFILE http://turs.infolinker.com.tw/x turs.infolinker.com.tw "Found proxy PROXY proxylib.ntou.edu.tw:3128" 395 | test_proxy $PACFILE http://tw.magv.com/x tw.magv.com "Found proxy PROXY proxylib.ntou.edu.tw:3128" 396 | test_proxy $PACFILE http://twu-ind.wisenews.net.tw/x twu-ind.wisenews.net.tw "Found proxy PROXY proxylib.ntou.edu.tw:3128" 397 | test_proxy $PACFILE http://udndata.com/x udndata.com "Found proxy PROXY proxylib.ntou.edu.tw:3128" 398 | test_proxy $PACFILE http://udndata.com/library/fullpage/x udndata.com/library/fullpage "Found proxy PROXY proxylib.ntou.edu.tw:3128" 399 | test_proxy $PACFILE http://ulej.stic.gov.tw/x ulej.stic.gov.tw "Found proxy PROXY proxylib.ntou.edu.tw:3128" 400 | test_proxy $PACFILE http://vnweb.hwwilsonweb.com/x vnweb.hwwilsonweb.com "Found proxy PROXY proxylib.ntou.edu.tw:3128" 401 | test_proxy $PACFILE http://wber.oupjournals.org/x wber.oupjournals.org "Found proxy PROXY proxylib.ntou.edu.tw:3128" 402 | test_proxy $PACFILE http://wbro.oupjournals.org/x wbro.oupjournals.org "Found proxy PROXY proxylib.ntou.edu.tw:3128" 403 | test_proxy $PACFILE http://wcs.webofknowledge.com/x wcs.webofknowledge.com "Found proxy PROXY proxylib.ntou.edu.tw:3128" 404 | test_proxy $PACFILE http://web.a.ebscohost.com/x web.a.ebscohost.com "Found proxy PROXY proxylib.ntou.edu.tw:3128" 405 | test_proxy $PACFILE http://web.b.ebscohost.com/x web.b.ebscohost.com "Found proxy PROXY proxylib.ntou.edu.tw:3128" 406 | test_proxy $PACFILE http://web.c.ebscohost.com/x web.c.ebscohost.com "Found proxy PROXY proxylib.ntou.edu.tw:3128" 407 | test_proxy $PACFILE http://web.d.ebscohost.com/x web.d.ebscohost.com "Found proxy PROXY proxylib.ntou.edu.tw:3128" 408 | test_proxy $PACFILE http://web.e.ebscohost.com/x web.e.ebscohost.com "Found proxy PROXY proxylib.ntou.edu.tw:3128" 409 | test_proxy $PACFILE http://web.ebscohost.com/x web.ebscohost.com "Found proxy PROXY proxylib.ntou.edu.tw:3128" 410 | test_proxy $PACFILE http://web.lexis-nexis.com/x web.lexis-nexis.com "Found proxy PROXY proxylib.ntou.edu.tw:3128" 411 | test_proxy $PACFILE http://web17.epnet.com/x web17.epnet.com "Found proxy PROXY proxylib.ntou.edu.tw:3128" 412 | test_proxy $PACFILE http://webofknowledge.com/x webofknowledge.com "Found proxy PROXY proxylib.ntou.edu.tw:3128" 413 | test_proxy $PACFILE http://wok-ws.isiknowledge.com/x wok-ws.isiknowledge.com "Found proxy PROXY proxylib.ntou.edu.tw:3128" 414 | test_proxy $PACFILE http://wos.stic.gov.tw/x wos.stic.gov.tw "Found proxy PROXY proxylib.ntou.edu.tw:3128" 415 | test_proxy $PACFILE http://ws.isiknowledge.com/x ws.isiknowledge.com "Found proxy PROXY proxylib.ntou.edu.tw:3128" 416 | test_proxy $PACFILE http://www.acm.org/x www.acm.org "Found proxy PROXY proxylib.ntou.edu.tw:3128" 417 | test_proxy $PACFILE http://www.agu.org/x www.agu.org "Found proxy PROXY proxylib.ntou.edu.tw:3128" 418 | test_proxy $PACFILE http://www.airitiaci.com/x www.airitiaci.com "Found proxy PROXY proxylib.ntou.edu.tw:3128" 419 | test_proxy $PACFILE http://www.airitiaci.com//x www.airitiaci.com/ "Found proxy PROXY proxylib.ntou.edu.tw:3128" 420 | test_proxy $PACFILE http://www.airitibooks.com/x www.airitibooks.com "Found proxy PROXY proxylib.ntou.edu.tw:3128" 421 | test_proxy $PACFILE http://www.airitilibrary.com/x www.airitilibrary.com "Found proxy PROXY proxylib.ntou.edu.tw:3128" 422 | test_proxy $PACFILE http://www.airitinature.com/x www.airitinature.com "Found proxy PROXY proxylib.ntou.edu.tw:3128" 423 | test_proxy $PACFILE http://www.annualreviews.org/x www.annualreviews.org "Found proxy PROXY proxylib.ntou.edu.tw:3128" 424 | test_proxy $PACFILE http://www.apabi.com/x www.apabi.com "Found proxy PROXY proxylib.ntou.edu.tw:3128" 425 | test_proxy $PACFILE http://www.apabi.com/cec/x www.apabi.com/cec "Found proxy PROXY proxylib.ntou.edu.tw:3128" 426 | test_proxy $PACFILE http://www.ascelibrary.org/x www.ascelibrary.org "Found proxy PROXY proxylib.ntou.edu.tw:3128" 427 | test_proxy $PACFILE http://www.asme.org/x www.asme.org "Found proxy PROXY proxylib.ntou.edu.tw:3128" 428 | test_proxy $PACFILE http://www.astm.org/x www.astm.org "Found proxy PROXY proxylib.ntou.edu.tw:3128" 429 | test_proxy $PACFILE http://www.atozmapsonline.com/x www.atozmapsonline.com "Found proxy PROXY proxylib.ntou.edu.tw:3128" 430 | test_proxy $PACFILE http://www.atoztheworld.com/x www.atoztheworld.com "Found proxy PROXY proxylib.ntou.edu.tw:3128" 431 | test_proxy $PACFILE http://www.atozworldbusiness.com/x www.atozworldbusiness.com "Found proxy PROXY proxylib.ntou.edu.tw:3128" 432 | test_proxy $PACFILE http://www.atozworldculture.com/x www.atozworldculture.com "Found proxy PROXY proxylib.ntou.edu.tw:3128" 433 | test_proxy $PACFILE http://www.atozworldtrade.com/x www.atozworldtrade.com "Found proxy PROXY proxylib.ntou.edu.tw:3128" 434 | test_proxy $PACFILE http://www.atozworldtravel.com/x www.atozworldtravel.com "Found proxy PROXY proxylib.ntou.edu.tw:3128" 435 | test_proxy $PACFILE http://www.biolbull.org/x www.biolbull.org "Found proxy PROXY proxylib.ntou.edu.tw:3128" 436 | test_proxy $PACFILE http://www.bioone.org/x www.bioone.org "Found proxy PROXY proxylib.ntou.edu.tw:3128" 437 | test_proxy $PACFILE http://www.blackwell-synergy.com/x www.blackwell-synergy.com "Found proxy PROXY proxylib.ntou.edu.tw:3128" 438 | test_proxy $PACFILE http://www.brepolis.net/x www.brepolis.net "Found proxy PROXY proxylib.ntou.edu.tw:3128" 439 | test_proxy $PACFILE http://www.bridgemaneducation.com/x www.bridgemaneducation.com "Found proxy PROXY proxylib.ntou.edu.tw:3128" 440 | test_proxy $PACFILE http://www.bssaonline.org/x www.bssaonline.org "Found proxy PROXY proxylib.ntou.edu.tw:3128" 441 | test_proxy $PACFILE http://www.cairn.info/x www.cairn.info "Found proxy PROXY proxylib.ntou.edu.tw:3128" 442 | test_proxy $PACFILE http://www.ceps.com.tw/x www.ceps.com.tw "Found proxy PROXY proxylib.ntou.edu.tw:3128" 443 | test_proxy $PACFILE http://www.chinamaxx.net/x www.chinamaxx.net "Found proxy PROXY proxylib.ntou.edu.tw:3128" 444 | test_proxy $PACFILE http://www.classiques-garnier.com/x www.classiques-garnier.com "Found proxy PROXY proxylib.ntou.edu.tw:3128" 445 | test_proxy $PACFILE http://www.cnsonline.com.tw/x www.cnsonline.com.tw "Found proxy PROXY proxylib.ntou.edu.tw:3128" 446 | test_proxy $PACFILE http://www.cnsppa.com.tw/x www.cnsppa.com.tw "Found proxy PROXY proxylib.ntou.edu.tw:3128" 447 | test_proxy $PACFILE http://www.crcnetbase.com/x www.crcnetbase.com "Found proxy PROXY proxylib.ntou.edu.tw:3128" 448 | test_proxy $PACFILE http://www.credoreference.com/x www.credoreference.com "Found proxy PROXY proxylib.ntou.edu.tw:3128" 449 | test_proxy $PACFILE http://www.csa.com/x www.csa.com "Found proxy PROXY proxylib.ntou.edu.tw:3128" 450 | test_proxy $PACFILE http://www.csa.com.tw/x www.csa.com.tw "Found proxy PROXY proxylib.ntou.edu.tw:3128" 451 | test_proxy $PACFILE http://www.dalloz.fr/x www.dalloz.fr "Found proxy PROXY proxylib.ntou.edu.tw:3128" 452 | test_proxy $PACFILE http://www.dialogselect.com/x www.dialogselect.com "Found proxy PROXY proxylib.ntou.edu.tw:3128" 453 | test_proxy $PACFILE http://www.discoverygate.com/x www.discoverygate.com "Found proxy PROXY proxylib.ntou.edu.tw:3128" 454 | test_proxy $PACFILE http://www.duxiu.com/x www.duxiu.com "Found proxy PROXY proxylib.ntou.edu.tw:3128" 455 | test_proxy $PACFILE http://www.ebookstore.tandf.co.uk/x www.ebookstore.tandf.co.uk "Found proxy PROXY proxylib.ntou.edu.tw:3128" 456 | test_proxy $PACFILE http://www.ebsco.com/x www.ebsco.com "Found proxy PROXY proxylib.ntou.edu.tw:3128" 457 | test_proxy $PACFILE http://www.educationarena.com/x www.educationarena.com "Found proxy PROXY proxylib.ntou.edu.tw:3128" 458 | test_proxy $PACFILE http://www.ei.org/x www.ei.org "Found proxy PROXY proxylib.ntou.edu.tw:3128" 459 | test_proxy $PACFILE http://www.els.net/x www.els.net "Found proxy PROXY proxylib.ntou.edu.tw:3128" 460 | test_proxy $PACFILE http://www.elsevier.com/x www.elsevier.com "Found proxy PROXY proxylib.ntou.edu.tw:3128" 461 | test_proxy $PACFILE http://www.emeraldinsight.com/x www.emeraldinsight.com "Found proxy PROXY proxylib.ntou.edu.tw:3128" 462 | test_proxy $PACFILE http://www.engineeringvillage.com/x www.engineeringvillage.com "Found proxy PROXY proxylib.ntou.edu.tw:3128" 463 | test_proxy $PACFILE http://www.engineeringvillage2.org/x www.engineeringvillage2.org "Found proxy PROXY proxylib.ntou.edu.tw:3128" 464 | test_proxy $PACFILE http://www.europaworld.com/x www.europaworld.com "Found proxy PROXY proxylib.ntou.edu.tw:3128" 465 | test_proxy $PACFILE http://www.europe.idealibrary.com/x www.europe.idealibrary.com "Found proxy PROXY proxylib.ntou.edu.tw:3128" 466 | test_proxy $PACFILE http://www.frantext.fr/x www.frantext.fr "Found proxy PROXY proxylib.ntou.edu.tw:3128" 467 | test_proxy $PACFILE http://www.genome.org/x www.genome.org "Found proxy PROXY proxylib.ntou.edu.tw:3128" 468 | test_proxy $PACFILE http://www.genomebiology.com/x www.genomebiology.com "Found proxy PROXY proxylib.ntou.edu.tw:3128" 469 | test_proxy $PACFILE http://www.greeninfoonline.com/x www.greeninfoonline.com "Found proxy PROXY proxylib.ntou.edu.tw:3128" 470 | test_proxy $PACFILE http://www.hepseu.com/x www.hepseu.com "Found proxy PROXY proxylib.ntou.edu.tw:3128" 471 | test_proxy $PACFILE http://www.icevirtuallibrary.com/x www.icevirtuallibrary.com "Found proxy PROXY proxylib.ntou.edu.tw:3128" 472 | test_proxy $PACFILE http://www.idealibrary.com/x www.idealibrary.com "Found proxy PROXY proxylib.ntou.edu.tw:3128" 473 | test_proxy $PACFILE http://www.igpublish.com/x www.igpublish.com "Found proxy PROXY proxylib.ntou.edu.tw:3128" 474 | test_proxy $PACFILE http://www.informaworld.com/x www.informaworld.com "Found proxy PROXY proxylib.ntou.edu.tw:3128" 475 | test_proxy $PACFILE http://www.ingenta.com/x www.ingenta.com "Found proxy PROXY proxylib.ntou.edu.tw:3128" 476 | test_proxy $PACFILE http://www.int-res.com/x www.int-res.com "Found proxy PROXY proxylib.ntou.edu.tw:3128" 477 | test_proxy $PACFILE http://www.iop.org/x www.iop.org "Found proxy PROXY proxylib.ntou.edu.tw:3128" 478 | test_proxy $PACFILE http://www.iospress.nl/x www.iospress.nl "Found proxy PROXY proxylib.ntou.edu.tw:3128" 479 | test_proxy $PACFILE http://www.isihighlycited.com/x www.isihighlycited.com "Found proxy PROXY proxylib.ntou.edu.tw:3128" 480 | test_proxy $PACFILE http://www.jkn21.com/x www.jkn21.com "Found proxy PROXY proxylib.ntou.edu.tw:3128" 481 | test_proxy $PACFILE http://www.jstor.org/x www.jstor.org "Found proxy PROXY proxylib.ntou.edu.tw:3128" 482 | test_proxy $PACFILE http://www.juris.de/x www.juris.de "Found proxy PROXY proxylib.ntou.edu.tw:3128" 483 | test_proxy $PACFILE http://www.kluwerlawonline.com/x www.kluwerlawonline.com "Found proxy PROXY proxylib.ntou.edu.tw:3128" 484 | test_proxy $PACFILE http://www.kluweronline.com/x www.kluweronline.com "Found proxy PROXY proxylib.ntou.edu.tw:3128" 485 | test_proxy $PACFILE http://www.knovel.com/x www.knovel.com "Found proxy PROXY proxylib.ntou.edu.tw:3128" 486 | test_proxy $PACFILE http://www.lawbank.com.tw/x www.lawbank.com.tw "Found proxy PROXY proxylib.ntou.edu.tw:3128" 487 | test_proxy $PACFILE http://www.lawdata.com.tw/x www.lawdata.com.tw "Found proxy PROXY proxylib.ntou.edu.tw:3128" 488 | test_proxy $PACFILE http://www.lexisnexis.com/x www.lexisnexis.com "Found proxy PROXY proxylib.ntou.edu.tw:3128" 489 | test_proxy $PACFILE http://www.lexisnexis.com/ap/academic/x www.lexisnexis.com/ap/academic "Found proxy PROXY proxylib.ntou.edu.tw:3128" 490 | test_proxy $PACFILE http://www.lexisnexis.com/ap/auth/x www.lexisnexis.com/ap/auth "Found proxy PROXY proxylib.ntou.edu.tw:3128" 491 | test_proxy $PACFILE http://www.lextenso.fr/x www.lextenso.fr "Found proxy PROXY proxylib.ntou.edu.tw:3128" 492 | test_proxy $PACFILE http://www.mergentonline.com/x www.mergentonline.com "Found proxy PROXY proxylib.ntou.edu.tw:3128" 493 | test_proxy $PACFILE http://www.mrw.interscience.wiley.com/x www.mrw.interscience.wiley.com "Found proxy PROXY proxylib.ntou.edu.tw:3128" 494 | test_proxy $PACFILE http://www.munzinger.de/x www.munzinger.de "Found proxy PROXY proxylib.ntou.edu.tw:3128" 495 | test_proxy $PACFILE http://www.myendnoteweb.com/x www.myendnoteweb.com "Found proxy PROXY proxylib.ntou.edu.tw:3128" 496 | test_proxy $PACFILE http://www.myilibrary.com/x www.myilibrary.com "Found proxy PROXY proxylib.ntou.edu.tw:3128" 497 | test_proxy $PACFILE http://www.nature.com/x www.nature.com "Found proxy PROXY proxylib.ntou.edu.tw:3128" 498 | test_proxy $PACFILE http://www.netlibrary.com/x www.netlibrary.com "Found proxy PROXY proxylib.ntou.edu.tw:3128" 499 | test_proxy $PACFILE http://www.nonlin-processes-geophys.net/x www.nonlin-processes-geophys.net "Found proxy PROXY proxylib.ntou.edu.tw:3128" 500 | test_proxy $PACFILE http://www.nutrition.org/x www.nutrition.org "Found proxy PROXY proxylib.ntou.edu.tw:3128" 501 | test_proxy $PACFILE http://www.onesource.com/x www.onesource.com "Found proxy PROXY proxylib.ntou.edu.tw:3128" 502 | test_proxy $PACFILE http://www.opticsexpress.org/x www.opticsexpress.org "Found proxy PROXY proxylib.ntou.edu.tw:3128" 503 | test_proxy $PACFILE http://www.osa-jon.org/x www.osa-jon.org "Found proxy PROXY proxylib.ntou.edu.tw:3128" 504 | test_proxy $PACFILE http://www.osa-opn.org/x www.osa-opn.org "Found proxy PROXY proxylib.ntou.edu.tw:3128" 505 | test_proxy $PACFILE http://www.oxfordreference.com/x www.oxfordreference.com "Found proxy PROXY proxylib.ntou.edu.tw:3128" 506 | test_proxy $PACFILE http://www.oxfordscholarship.com/x www.oxfordscholarship.com "Found proxy PROXY proxylib.ntou.edu.tw:3128" 507 | test_proxy $PACFILE http://www.palgrave-journals.com/x www.palgrave-journals.com "Found proxy PROXY proxylib.ntou.edu.tw:3128" 508 | test_proxy $PACFILE http://www.palgraveconnect.com/x www.palgraveconnect.com "Found proxy PROXY proxylib.ntou.edu.tw:3128" 509 | test_proxy $PACFILE http://www.proteinscience.org/x www.proteinscience.org "Found proxy PROXY proxylib.ntou.edu.tw:3128" 510 | test_proxy $PACFILE http://www.read.com.tw/x www.read.com.tw "Found proxy PROXY proxylib.ntou.edu.tw:3128" 511 | test_proxy $PACFILE http://www.reaxys.com/x www.reaxys.com "Found proxy PROXY proxylib.ntou.edu.tw:3128" 512 | test_proxy $PACFILE http://www.refworks.com/x www.refworks.com "Found proxy PROXY proxylib.ntou.edu.tw:3128" 513 | test_proxy $PACFILE http://www.refworks.com.tw/x www.refworks.com.tw "Found proxy PROXY proxylib.ntou.edu.tw:3128" 514 | test_proxy $PACFILE http://www.researcherid.com/x www.researcherid.com "Found proxy PROXY proxylib.ntou.edu.tw:3128" 515 | test_proxy $PACFILE http://www.rsc.org/x www.rsc.org "Found proxy PROXY proxylib.ntou.edu.tw:3128" 516 | test_proxy $PACFILE http://www.sage-ereference.com/x www.sage-ereference.com "Found proxy PROXY proxylib.ntou.edu.tw:3128" 517 | test_proxy $PACFILE http://www.sciencedirect.com/x www.sciencedirect.com "Found proxy PROXY proxylib.ntou.edu.tw:3128" 518 | test_proxy $PACFILE http://www.sciencemag.org/x www.sciencemag.org "Found proxy PROXY proxylib.ntou.edu.tw:3128" 519 | test_proxy $PACFILE http://www.scopus.com/x www.scopus.com "Found proxy PROXY proxylib.ntou.edu.tw:3128" 520 | test_proxy $PACFILE http://www.springerlink.com/x www.springerlink.com "Found proxy PROXY proxylib.ntou.edu.tw:3128" 521 | test_proxy $PACFILE http://www.swetsnet.nl/x www.swetsnet.nl "Found proxy PROXY proxylib.ntou.edu.tw:3128" 522 | test_proxy $PACFILE http://www.swetswise.com/x www.swetswise.com "Found proxy PROXY proxylib.ntou.edu.tw:3128" 523 | test_proxy $PACFILE http://www.taebcnetbase.com/x www.taebcnetbase.com "Found proxy PROXY proxylib.ntou.edu.tw:3128" 524 | test_proxy $PACFILE http://www.tandf.co.uk/x www.tandf.co.uk "Found proxy PROXY proxylib.ntou.edu.tw:3128" 525 | test_proxy $PACFILE http://www.tandfonline.com/x www.tandfonline.com "Found proxy PROXY proxylib.ntou.edu.tw:3128" 526 | test_proxy $PACFILE http://www.tbmc.com.tw/x www.tbmc.com.tw "Found proxy PROXY proxylib.ntou.edu.tw:3128" 527 | test_proxy $PACFILE http://www.TeacherReference.com/x www.TeacherReference.com "Found proxy PROXY proxylib.ntou.edu.tw:3128" 528 | test_proxy $PACFILE http://www.tlemea.com/x www.tlemea.com "Found proxy PROXY proxylib.ntou.edu.tw:3128" 529 | test_proxy $PACFILE http://www.tls.psmedia.com/x www.tls.psmedia.com "Found proxy PROXY proxylib.ntou.edu.tw:3128" 530 | test_proxy $PACFILE http://www.tumblebooks.com/x www.tumblebooks.com "Found proxy PROXY proxylib.ntou.edu.tw:3128" 531 | test_proxy $PACFILE http://www.tw-elsevier.com/x www.tw-elsevier.com "Found proxy PROXY proxylib.ntou.edu.tw:3128" 532 | test_proxy $PACFILE http://www.universalis-edu.com/x www.universalis-edu.com "Found proxy PROXY proxylib.ntou.edu.tw:3128" 533 | test_proxy $PACFILE http://www.wanfangdata.com.hk/x www.wanfangdata.com.hk "Found proxy PROXY proxylib.ntou.edu.tw:3128" 534 | test_proxy $PACFILE http://www.webofknowledge.com/x www.webofknowledge.com "Found proxy PROXY proxylib.ntou.edu.tw:3128" 535 | test_proxy $PACFILE http://www.webofknowledgev4.com/x www.webofknowledgev4.com "Found proxy PROXY proxylib.ntou.edu.tw:3128" 536 | test_proxy $PACFILE http://www.westlaw.com/x www.westlaw.com "Found proxy PROXY proxylib.ntou.edu.tw:3128" 537 | test_proxy $PACFILE http://www.wkap.nl/x www.wkap.nl "Found proxy PROXY proxylib.ntou.edu.tw:3128" 538 | test_proxy $PACFILE http://www2.astm.org/x www2.astm.org "Found proxy PROXY proxylib.ntou.edu.tw:3128" 539 | test_proxy $PACFILE http://www2.read.com.tw/x www2.read.com.tw "Found proxy PROXY proxylib.ntou.edu.tw:3128" 540 | test_proxy $PACFILE http://www3.electrochem.org/x www3.electrochem.org "Found proxy PROXY proxylib.ntou.edu.tw:3128" 541 | test_proxy $PACFILE http://www3.interscience.wiley.com/x www3.interscience.wiley.com "Found proxy PROXY proxylib.ntou.edu.tw:3128" 542 | test_proxy $PACFILE http://www3.oup.co.uk/x www3.oup.co.uk "Found proxy PROXY proxylib.ntou.edu.tw:3128" 543 | test_proxy $PACFILE http://wwwlib.global.umi.com/x wwwlib.global.umi.com "Found proxy PROXY proxylib.ntou.edu.tw:3128" 544 | test_proxy $PACFILE http://yagi.jkn21.com/x yagi.jkn21.com "Found proxy PROXY proxylib.ntou.edu.tw:3128" 545 | test_proxy $PACFILE http://google.com/x google.com "Found proxy DIRECT" 546 | 547 | exit $RETVAL 548 | -------------------------------------------------------------------------------- /tests/test3.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | RETVAL=0 4 | 5 | PACFILE="3.js" 6 | 7 | . ./test_helper 8 | 9 | test_proxy $PACFILE http://foobar.example.com/x foobar.example.com "Found proxy DIRECT" 10 | test_proxy $PACFILE http://10.0.0.10/x 10.0.0.10 "Found proxy PROXY fastproxy.example.com:8080" 11 | test_proxy $PACFILE http://129.35.213.31/x 129.35.213.31 "Found proxy PROXY proxy.example.com:8080; DIRECT" 12 | 13 | exit $RETVAL 14 | -------------------------------------------------------------------------------- /tests/test4.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | RETVAL=0 4 | 5 | PACFILE="1.js" 6 | 7 | DATA="" 8 | 9 | for i in $(seq 1 100); do 10 | DATA="http://google.com/${i} google.com ${DATA}" 11 | done 12 | 13 | echo $DATA 14 | 15 | ./test_pac $PACFILE $DATA 16 | 17 | exit $RETVAL 18 | -------------------------------------------------------------------------------- /tests/test5.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | RETVAL=0 4 | 5 | PACFILE="4.js" 6 | 7 | . ./test_helper 8 | 9 | test_error $PACFILE http://foobar.example.com/x foobar.example.com "Javascript call failed: testing error handling" 10 | 11 | exit $RETVAL 12 | -------------------------------------------------------------------------------- /tests/test6.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | RETVAL=0 4 | 5 | PACFILE="5.js" 6 | 7 | . ./test_helper 8 | 9 | test_error $PACFILE http://foobar.example.com/x foobar.example.com "Javascript call failed: Error: testing error handling" 10 | 11 | exit $RETVAL 12 | -------------------------------------------------------------------------------- /tests/test7.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | RETVAL=0 4 | 5 | PACFILE="6.js" 6 | 7 | . ./test_helper 8 | 9 | test_proxy $PACFILE http://this.domain.does.not.exist/ this.domain.does.not.exist "Found proxy PROXY :8080" 10 | 11 | exit $RETVAL 12 | -------------------------------------------------------------------------------- /tests/test_helper: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | rm -f core* 4 | ulimit -c unlimited 5 | 6 | check_corefile() { 7 | if test -n "$(find . -maxdepth 1 -name 'core*' -print -quit)"; then 8 | echo "Found corefile, trying to get stack trace." 9 | gdb --batch --quiet -ex "thread apply all bt full" -ex "quit" .libs/lt-test_pac core* 10 | rm core* 11 | fi 12 | } 13 | 14 | test_proxy() { 15 | _pacfile="$1" 16 | _url="$2" 17 | _host="$3" 18 | _expected_proxy="$4" 19 | _res=$(./test_pac "$_pacfile" $_url $_host) 20 | if [ "$_res" != "$_expected_proxy" ]; then 21 | echo "FAILED:" $_res "!=" $_expected_proxy 22 | check_corefile 23 | RETVAL=1 24 | else 25 | echo "OK:" $_url $_host "->" $_res 26 | fi 27 | } 28 | 29 | test_error() { 30 | _pacfile="$1" 31 | _url="$2" 32 | _host="$3" 33 | _expected_error="$4" 34 | _res=$(./test_pac "$_pacfile" $_url $_host 2>&1 | grep "$_expected_error") 35 | if [ -z "$_res" ]; then 36 | echo "FAILED: expected error message \"$_expected_error\"" 37 | check_corefile 38 | RETVAL=1 39 | else 40 | echo "OK:" $_url $_host "->" $_res 41 | fi 42 | } 43 | -------------------------------------------------------------------------------- /tests/test_helper.h: -------------------------------------------------------------------------------- 1 | #if defined(_WIN32) || defined(__CYGWIN__) 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | int init_socket(void) 9 | { 10 | int err; 11 | WORD wVersionRequested; 12 | WSADATA wsaData; 13 | 14 | wVersionRequested = MAKEWORD(2, 2); 15 | 16 | err = WSAStartup(wVersionRequested, &wsaData); 17 | if (err != 0) { 18 | printf("WSAStartup failed with error: %d\n", err); 19 | return 1; 20 | } 21 | 22 | return 0; 23 | } 24 | 25 | #else 26 | 27 | #include 28 | 29 | int init_socket(void) 30 | { 31 | return 0; 32 | } 33 | 34 | #endif 35 | 36 | -------------------------------------------------------------------------------- /tests/test_pac.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #if defined(_WIN32) || defined(__CYGWIN__) 12 | #include 13 | #else 14 | #include 15 | #include 16 | #endif 17 | #if defined(__APPLE__) 18 | #include 19 | #endif 20 | 21 | #include "pac.h" 22 | 23 | struct pac *pac; 24 | 25 | #if defined(_WIN32) || defined(__CYGWIN__) 26 | #define ERR() WSAGetLastError() 27 | #else 28 | #define ERR() errno 29 | #endif 30 | 31 | #if defined(_WIN32) || defined(__CYGWIN__) 32 | typedef SOCKET notifier_t; 33 | #else 34 | typedef int notifier_t; 35 | #endif 36 | 37 | void do_notify(notifier_t n) 38 | { 39 | int ret; 40 | 41 | #if defined(_WIN32) || defined(__CYGWIN__) 42 | ret = send(n, "x", 1, 0); 43 | #else 44 | ret = write(n, "x", 1); 45 | #endif 46 | if (ret < 0) 47 | fprintf(stderr, "Error sending notification (error code %d)\n", ERR()); 48 | } 49 | 50 | int is_notified(notifier_t n, struct timeval *timeout) 51 | { 52 | fd_set fds; 53 | 54 | FD_ZERO(&fds); 55 | FD_SET(n, &fds); 56 | 57 | #if defined(_WIN32) || defined(__CYGWIN__) 58 | char buf[64]; 59 | if (select(100000, &fds, NULL, NULL, timeout) > 0) { 60 | recv(n, buf, sizeof(buf), 0); 61 | #else 62 | unsigned char buf[64]; 63 | if (select(n + 1, &fds, NULL, NULL, timeout) > 0) { 64 | int rc = read(n, buf, sizeof(buf)); 65 | if (rc < 0) { 66 | fprintf(stderr, "Warning, notifier socket error\n"); 67 | perror("read()"); 68 | } else if (rc == 0) { 69 | fprintf(stderr, "Warning, notifier socket EOF\n"); 70 | } 71 | #endif 72 | return 1; 73 | } else { 74 | return 0; 75 | } 76 | } 77 | 78 | /* 79 | * Based on evutil_socketpair() from libevent. 80 | */ 81 | int create_notifier(notifier_t not[2]) 82 | { 83 | #if defined(_WIN32) || defined(__CYGWIN__) 84 | SOCKET listener = -1, connector = -1, acceptor = -1; 85 | struct sockaddr_in listen_addr, connect_addr; 86 | int size; 87 | 88 | listener = socket(AF_INET, SOCK_STREAM, 0); 89 | if (listener < 0) 90 | return -1; 91 | memset(&listen_addr, 0, sizeof(listen_addr)); 92 | listen_addr.sin_family = AF_INET; 93 | listen_addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK); 94 | listen_addr.sin_port = 0; /* kernel chooses port. */ 95 | if (bind(listener, (struct sockaddr *) &listen_addr, sizeof (listen_addr)) 96 | == -1) 97 | goto out; 98 | if (listen(listener, 1) == -1) 99 | goto out; 100 | 101 | connector = socket(AF_INET, SOCK_STREAM, 0); 102 | if (connector < 0) 103 | goto out; 104 | 105 | /* We want to find out the port number to connect to. */ 106 | size = sizeof(connect_addr); 107 | if (getsockname(listener, (struct sockaddr *) &connect_addr, &size) == -1) 108 | goto out; 109 | if (size != sizeof(connect_addr)) 110 | goto out; 111 | if (connect(connector, (struct sockaddr *) &connect_addr, 112 | sizeof(connect_addr)) == -1) 113 | goto out; 114 | 115 | size = sizeof(listen_addr); 116 | acceptor = accept(listener, (struct sockaddr *) &listen_addr, &size); 117 | if (acceptor < 0) 118 | goto out; 119 | if (size != sizeof(listen_addr)) 120 | goto out; 121 | /* Now check we are talking to ourself by matching port and host on the 122 | two sockets. */ 123 | if (getsockname(connector, (struct sockaddr *) &connect_addr, &size) == -1) 124 | goto out; 125 | if (size != sizeof(connect_addr) 126 | || listen_addr.sin_family != connect_addr.sin_family 127 | || listen_addr.sin_addr.s_addr != connect_addr.sin_addr.s_addr 128 | || listen_addr.sin_port != connect_addr.sin_port) 129 | goto out; 130 | closesocket(listener); 131 | not[0] = (int)connector; 132 | not[1] = (int)acceptor; 133 | 134 | return 0; 135 | 136 | out: 137 | if (listener != -1) 138 | closesocket(listener); 139 | if (connector != -1) 140 | closesocket(connector); 141 | if (acceptor != -1) 142 | closesocket(acceptor); 143 | return -1; 144 | #else 145 | return pipe(not); 146 | #endif 147 | } 148 | 149 | static void usage(char *prog) 150 | { 151 | fprintf(stderr, "Usage: %s [ ...]\n", 152 | prog); 153 | fflush(stderr); 154 | exit(1); 155 | } 156 | 157 | static void notify(void *arg) 158 | { 159 | do_notify((notifier_t)(long)arg); 160 | } 161 | 162 | static int finished = 0; 163 | 164 | static void proxy_found(char *proxy, void *arg) 165 | { 166 | printf("Found proxy %s\n", proxy); 167 | free(proxy); 168 | finished++; 169 | } 170 | 171 | static char *read_pacfile(char *pacfile) 172 | { 173 | char *js = NULL; 174 | int fd = open(pacfile, O_RDONLY); 175 | if (fd < 0) { 176 | fprintf(stderr, "Error opening file %s\n", pacfile); 177 | goto err; 178 | } 179 | 180 | size_t js_sz = 8192, offset = 0; 181 | js = calloc(1, js_sz); 182 | if (!js) { 183 | fprintf(stderr, "Error allocating memory for PAC file\n"); 184 | goto err; 185 | } 186 | for (;;) { 187 | int rc = read(fd, js + offset, js_sz - offset); 188 | if (rc == 0) { 189 | break; 190 | } else if (rc < 0) { 191 | fprintf(stderr, "Error reading from file %s\n", pacfile); 192 | perror("read()"); 193 | goto err; 194 | } 195 | 196 | offset += rc; 197 | if (offset == js_sz) { 198 | js_sz *= 2; 199 | js = realloc(js, js_sz); 200 | if (!js) { 201 | fprintf(stderr, "Error allocating memory for PAC file\n"); 202 | goto err; 203 | } 204 | } 205 | } 206 | 207 | close(fd); 208 | return js; 209 | 210 | err: 211 | if (fd >= 0) 212 | close(fd); 213 | if (js) 214 | free(js); 215 | return NULL; 216 | } 217 | 218 | int main(int argc, char *argv[]) 219 | { 220 | int i, ret = 1; 221 | char *url, *host, *js; 222 | struct timeval tv; 223 | notifier_t n[2]; 224 | 225 | #if defined(_WIN32) || defined(__CYGWIN__) 226 | WSADATA wsaData; 227 | if (WSAStartup(0x202, &wsaData)) { 228 | fprintf(stderr, "Failed to initialize WSA\n"); 229 | exit(1); 230 | } 231 | #endif 232 | 233 | if (argc <= 2 || argc % 2 != 0) 234 | usage(argv[0]); 235 | 236 | js = read_pacfile(argv[1]); 237 | if (!js) 238 | goto out; 239 | 240 | if (create_notifier(n) < 0) { 241 | fprintf(stderr, "Failed to create notifier\n"); 242 | goto out; 243 | } 244 | 245 | pac = pac_init(js, 16, notify, (void *)(long)n[1]); 246 | 247 | for (i = 2; i < argc; i += 2) { 248 | url = argv[i]; 249 | host = argv[i + 1]; 250 | pac_find_proxy(pac, url, host, proxy_found, NULL); 251 | tv.tv_sec = 0; 252 | tv.tv_usec = 0; 253 | if (is_notified(n[0], &tv)) 254 | pac_run_callbacks(pac); 255 | } 256 | 257 | i = 0; 258 | while (finished < argc / 2 - 1) { 259 | tv.tv_sec = 0; 260 | tv.tv_usec = 10000; 261 | if (is_notified(n[0], &tv)) 262 | pac_run_callbacks(pac); 263 | if (++i > 60 * 100) 264 | goto out; 265 | } 266 | 267 | ret = 0; 268 | 269 | out: 270 | free(js); 271 | return ret; 272 | } 273 | -------------------------------------------------------------------------------- /tests/test_unit1.c: -------------------------------------------------------------------------------- 1 | #include "greatest.h" 2 | 3 | #include "pac.h" 4 | 5 | SUITE(suite); 6 | 7 | TEST pac_init_valid_js(void) 8 | { 9 | char *js = "function FindProxyForURL(u, h) { return \"DIRECT\"; }"; 10 | 11 | ASSERT(pac_init(js, 1, NULL, NULL) != NULL); 12 | 13 | PASS(); 14 | } 15 | 16 | TEST pac_init_invalid_js(void) 17 | { 18 | char *js = "function FindProxyForURL(u, h) { return \"DIRECT\"; } foo;"; 19 | 20 | ASSERT(pac_init(js, 1, NULL, NULL) == NULL); 21 | 22 | PASS(); 23 | } 24 | 25 | GREATEST_SUITE(suite) 26 | { 27 | RUN_TEST(pac_init_valid_js); 28 | RUN_TEST(pac_init_invalid_js); 29 | } 30 | 31 | GREATEST_MAIN_DEFS(); 32 | 33 | int main(int argc, char **argv) 34 | { 35 | GREATEST_MAIN_BEGIN(); /* command-line arguments, initialization. */ 36 | RUN_SUITE(suite); 37 | GREATEST_MAIN_END(); /* display results */ 38 | } 39 | -------------------------------------------------------------------------------- /tests/test_unit2.c: -------------------------------------------------------------------------------- 1 | #include "test_helper.h" 2 | 3 | #include "greatest.h" 4 | 5 | #include "util.h" 6 | 7 | SUITE(suite); 8 | 9 | TEST test_my_ip_address_one(void) 10 | { 11 | int ret, i; 12 | char buf[256]; 13 | struct in_addr in; 14 | struct in6_addr in6; 15 | 16 | ret = util_my_ip_address(buf, sizeof(buf), 0); 17 | ASSERT(ret >= 0); 18 | 19 | for (i = 0; i < strlen(buf); i++) 20 | ASSERT(buf[i] != ';'); 21 | 22 | ASSERT(inet_pton(AF_INET, buf, &in) == 1 || 23 | inet_pton(AF_INET6, buf, &in6) == 1); 24 | 25 | PASS(); 26 | } 27 | 28 | TEST test_my_ip_address_all(void) 29 | { 30 | int ret; 31 | char buf[256], *ip = &buf[0], *needle; 32 | struct in_addr in; 33 | struct in6_addr in6; 34 | 35 | ret = util_my_ip_address(buf, sizeof(buf), 1); 36 | ASSERT(ret >= 0); 37 | 38 | for (;;) { 39 | needle = strchr(ip, ';'); 40 | if (needle) 41 | *needle = '\0'; 42 | ASSERT(inet_pton(AF_INET, ip, &in) == 1 || 43 | inet_pton(AF_INET6, ip, &in6) == 1); 44 | if (needle) 45 | ip = needle + 1; 46 | else 47 | break; 48 | } 49 | 50 | PASS(); 51 | } 52 | 53 | GREATEST_SUITE(suite) 54 | { 55 | RUN_TEST(test_my_ip_address_one); 56 | RUN_TEST(test_my_ip_address_all); 57 | } 58 | 59 | GREATEST_MAIN_DEFS(); 60 | 61 | int main(int argc, char **argv) 62 | { 63 | init_socket(); 64 | 65 | GREATEST_MAIN_BEGIN(); 66 | RUN_SUITE(suite); 67 | GREATEST_MAIN_END(); 68 | } 69 | -------------------------------------------------------------------------------- /tests/test_unit3.c: -------------------------------------------------------------------------------- 1 | #include "test_helper.h" 2 | 3 | #include "greatest.h" 4 | 5 | #include "util.h" 6 | 7 | SUITE(suite); 8 | 9 | TEST test_dns_resolve_one(void) 10 | { 11 | int ret; 12 | char buf[256]; 13 | struct in_addr in; 14 | struct in6_addr in6; 15 | 16 | ret = util_dns_resolve("www.google.com", buf, sizeof(buf), 0); 17 | ASSERT(ret >= 0); 18 | 19 | ASSERT(inet_pton(AF_INET, buf, &in) == 1 || 20 | inet_pton(AF_INET6, buf, &in6) == 1); 21 | 22 | PASS(); 23 | } 24 | 25 | TEST test_dns_resolve_all(void) 26 | { 27 | int ret; 28 | char buf[256], *ip = &buf[0], *needle; 29 | struct in_addr in; 30 | struct in6_addr in6; 31 | 32 | ret = util_dns_resolve("www.google.com", buf, sizeof(buf), 1); 33 | ASSERT(ret >= 0); 34 | 35 | for (;;) { 36 | needle = strchr(ip, ';'); 37 | if (needle) 38 | *needle = '\0'; 39 | ASSERT(inet_pton(AF_INET, ip, &in) == 1 || 40 | inet_pton(AF_INET6, ip, &in6) == 1); 41 | if (needle) 42 | ip = needle + 1; 43 | else 44 | break; 45 | } 46 | 47 | PASS(); 48 | } 49 | 50 | GREATEST_SUITE(suite) 51 | { 52 | RUN_TEST(test_dns_resolve_one); 53 | RUN_TEST(test_dns_resolve_all); 54 | } 55 | 56 | GREATEST_MAIN_DEFS(); 57 | 58 | int main(int argc, char **argv) 59 | { 60 | init_socket(); 61 | 62 | GREATEST_MAIN_BEGIN(); 63 | RUN_SUITE(suite); 64 | GREATEST_MAIN_END(); 65 | } 66 | -------------------------------------------------------------------------------- /threadpool.c: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2009 by Juliusz Chroboczek 3 | 4 | Permission is hereby granted, free of charge, to any person obtaining a copy 5 | of this software and associated documentation files (the "Software"), to deal 6 | in the Software without restriction, including without limitation the rights 7 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | copies of the Software, and to permit persons to whom the Software is 9 | furnished to do so, subject to the following conditions: 10 | 11 | The above copyright notice and this permission notice shall be included in 12 | all copies or substantial portions of the Software. 13 | 14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 20 | THE SOFTWARE. 21 | */ 22 | 23 | #include 24 | #include 25 | #include 26 | #include 27 | #include 28 | #include 29 | 30 | #include "threadpool.h" 31 | 32 | 33 | #if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201112L 34 | 35 | #include 36 | 37 | typedef atomic_int threadpool_atomic; 38 | 39 | static inline int 40 | atomic_test(threadpool_atomic *a) 41 | { 42 | return !!atomic_load_explicit(a, memory_order_acquire); 43 | } 44 | 45 | static inline void 46 | atomic_set(threadpool_atomic *a) 47 | { 48 | atomic_store_explicit(a, 1, memory_order_release); 49 | } 50 | 51 | static inline void 52 | atomic_reset(threadpool_atomic *a) 53 | { 54 | atomic_store_explicit(a, 0, memory_order_release); 55 | } 56 | 57 | #elif defined(__GNUC__) && \ 58 | (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 7)) 59 | 60 | typedef int threadpool_atomic; 61 | 62 | static inline int 63 | atomic_test(threadpool_atomic *a) 64 | { 65 | return !!__atomic_load_n(a, __ATOMIC_ACQUIRE); 66 | } 67 | 68 | static inline void 69 | atomic_set(threadpool_atomic *a) 70 | { 71 | __atomic_store_n(a, 1, __ATOMIC_RELEASE); 72 | } 73 | 74 | static inline void 75 | atomic_reset(threadpool_atomic *a) 76 | { 77 | __atomic_store_n(a, 0, __ATOMIC_RELEASE); 78 | } 79 | 80 | #else 81 | 82 | /* Since every lock acts as a memory barrier, and we only ever modify 83 | atomics under a lock, this is mostly safe. Note however that 84 | threadpool_run_callbacks might in principle get a stale copy. */ 85 | 86 | typedef volatile int threadpool_atomic; 87 | 88 | static inline int 89 | atomic_test(threadpool_atomic *a) 90 | { 91 | return *a; 92 | } 93 | 94 | static inline void 95 | atomic_set(threadpool_atomic *a) 96 | { 97 | *a = 1; 98 | } 99 | 100 | static inline void 101 | atomic_reset(threadpool_atomic *a) 102 | { 103 | *a = 0; 104 | } 105 | 106 | #endif 107 | 108 | typedef struct threadpool_item { 109 | threadpool_func_t *func; 110 | void *closure; 111 | struct threadpool_item *next; 112 | } threadpool_item_t; 113 | 114 | typedef struct threadpool_queue { 115 | threadpool_item_t *first; 116 | threadpool_item_t *last; 117 | } threadpool_queue_t; 118 | 119 | struct threadpool { 120 | int maxthreads, threads, idle; 121 | threadpool_queue_t scheduled, scheduled_back; 122 | /* Set when we request that all threads die. */ 123 | int dying; 124 | /* If this is false, we are guaranteed that scheduled_back is empty. */ 125 | threadpool_atomic have_scheduled_back; 126 | /* Protects everything except the atomics above. */ 127 | pthread_mutex_t lock; 128 | /* Signalled whenever a new continuation is enqueued or dying is set. */ 129 | pthread_cond_t cond; 130 | /* Signalled whenever a thread dies. */ 131 | pthread_cond_t die_cond; 132 | threadpool_func_t *wakeup; 133 | void *wakeup_closure; 134 | }; 135 | 136 | threadpool_t * 137 | threadpool_create(int maxthreads, 138 | threadpool_func_t *wakeup, void *wakeup_closure) 139 | { 140 | threadpool_t *tp; 141 | tp = calloc(1, sizeof(threadpool_t)); 142 | if(tp == NULL) 143 | return NULL; 144 | 145 | tp->maxthreads = maxthreads; 146 | tp->wakeup = wakeup; 147 | tp->wakeup_closure = wakeup_closure; 148 | pthread_mutex_init(&tp->lock, NULL); 149 | pthread_cond_init(&tp->cond, NULL); 150 | pthread_cond_init(&tp->die_cond, NULL); 151 | 152 | return tp; 153 | } 154 | 155 | int 156 | threadpool_die(threadpool_t *threadpool, int canblock) 157 | { 158 | int done; 159 | 160 | pthread_mutex_lock(&threadpool->lock); 161 | 162 | threadpool->dying = 1; 163 | pthread_cond_broadcast(&threadpool->cond); 164 | 165 | while(threadpool->threads > 0) { 166 | if(threadpool->scheduled_back.first || !canblock) 167 | break; 168 | pthread_cond_wait(&threadpool->die_cond, &threadpool->lock); 169 | } 170 | 171 | done = threadpool->threads == 0; 172 | 173 | pthread_mutex_unlock(&threadpool->lock); 174 | return done; 175 | } 176 | 177 | int 178 | threadpool_destroy(threadpool_t *threadpool) 179 | { 180 | int dead; 181 | 182 | pthread_mutex_lock(&threadpool->lock); 183 | dead = 184 | threadpool->threads == 0 && 185 | threadpool->scheduled.first == NULL && 186 | threadpool->scheduled_back.first == NULL; 187 | pthread_mutex_unlock(&threadpool->lock); 188 | 189 | if(!dead) 190 | return -1; 191 | 192 | pthread_cond_destroy(&threadpool->cond); 193 | pthread_cond_destroy(&threadpool->die_cond); 194 | pthread_mutex_destroy(&threadpool->lock); 195 | free(threadpool); 196 | return 1; 197 | } 198 | 199 | static threadpool_item_t * 200 | threadpool_dequeue(threadpool_queue_t *queue) 201 | { 202 | threadpool_item_t *item; 203 | 204 | if(queue->first == NULL) 205 | return NULL; 206 | 207 | item = queue->first; 208 | queue->first = item->next; 209 | if(item->next == NULL) 210 | queue->last = NULL; 211 | return item; 212 | } 213 | 214 | static void * 215 | thread_main(void *pool) 216 | { 217 | threadpool_t *threadpool = pool; 218 | threadpool_item_t *item; 219 | threadpool_func_t *func; 220 | void *closure; 221 | 222 | again: 223 | pthread_mutex_lock(&threadpool->lock); 224 | 225 | if(threadpool->scheduled.first == NULL) { 226 | struct timespec ts; 227 | 228 | if(threadpool->dying) 229 | goto die; 230 | 231 | /* Beware when benchmarking. Under Linux with NPTL, idle threads 232 | are slightly counter-productive in some benchmarks, but 233 | extremely productive in others. */ 234 | 235 | /* This constant may need to be tweaked. */ 236 | if(threadpool->idle >= 2) 237 | goto die; 238 | 239 | /* Don't bother with POSIX clocks. */ 240 | ts.tv_sec = time(NULL) + 1; 241 | ts.tv_nsec = 0; 242 | 243 | threadpool->idle++; 244 | pthread_cond_timedwait(&threadpool->cond, &threadpool->lock, &ts); 245 | threadpool->idle--; 246 | if(threadpool->scheduled.first == NULL) 247 | goto die; 248 | } 249 | 250 | item = threadpool_dequeue(&threadpool->scheduled); 251 | pthread_mutex_unlock(&threadpool->lock); 252 | 253 | func = item->func; 254 | closure = item->closure; 255 | free(item); 256 | 257 | func(closure); 258 | goto again; 259 | 260 | die: 261 | threadpool->threads--; 262 | pthread_cond_broadcast(&threadpool->die_cond); 263 | pthread_mutex_unlock(&threadpool->lock); 264 | return NULL; 265 | } 266 | 267 | /* This is called with the pool locked. */ 268 | static int 269 | threadpool_new_thread(threadpool_t *threadpool) 270 | { 271 | pthread_t thread; 272 | pthread_attr_t attr; 273 | int rc; 274 | 275 | assert(threadpool->threads < threadpool->maxthreads); 276 | 277 | pthread_attr_init(&attr); 278 | pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); 279 | rc = pthread_create(&thread, &attr, thread_main, (void*)threadpool); 280 | if(rc) { 281 | errno = rc; 282 | return -1; 283 | } 284 | threadpool->threads++; 285 | return 1; 286 | } 287 | 288 | /* There's a reason for the inconvenient interface: we want to perform the 289 | allocation outside of the critical region, and only take the lock when 290 | inserting the new cell. */ 291 | 292 | static threadpool_item_t * 293 | threadpool_item_alloc(threadpool_func_t *func, void *closure) 294 | { 295 | threadpool_item_t *item; 296 | 297 | item = malloc(sizeof(threadpool_item_t)); 298 | if(item == NULL) 299 | return NULL; 300 | 301 | item->func = func; 302 | item->closure = closure; 303 | item->next = NULL; 304 | 305 | return item; 306 | } 307 | 308 | static void 309 | threadpool_enqueue(threadpool_queue_t *queue, threadpool_item_t *item) 310 | { 311 | item->next = NULL; 312 | if(queue->last) 313 | queue->last->next = item; 314 | else 315 | queue->first = item; 316 | queue->last = item; 317 | } 318 | 319 | int 320 | threadpool_schedule(threadpool_t *threadpool, 321 | threadpool_func_t *func, void *closure) 322 | { 323 | threadpool_item_t *item; 324 | int rc = 0; 325 | int dosignal = 1; 326 | 327 | item = threadpool_item_alloc(func, closure); 328 | if(item == NULL) 329 | return -1; 330 | 331 | pthread_mutex_lock(&threadpool->lock); 332 | threadpool_enqueue(&threadpool->scheduled, item); 333 | if(threadpool->idle == 0) { 334 | dosignal = 0; 335 | if(threadpool->threads < threadpool->maxthreads) { 336 | rc = threadpool_new_thread(threadpool); 337 | if(rc < 0 && threadpool->threads > 0) 338 | rc = 0; /* we'll recover */ 339 | } 340 | } 341 | if(dosignal) 342 | pthread_cond_signal(&threadpool->cond); 343 | pthread_mutex_unlock(&threadpool->lock); 344 | 345 | return rc; 346 | } 347 | 348 | int 349 | threadpool_schedule_back(threadpool_t *threadpool, 350 | threadpool_func_t *func, void *closure) 351 | { 352 | threadpool_item_t *item; 353 | int wake = 1; 354 | 355 | item = threadpool_item_alloc(func, closure); 356 | if(item == NULL) 357 | return -1; 358 | 359 | pthread_mutex_lock(&threadpool->lock); 360 | if(atomic_test(&threadpool->have_scheduled_back)) 361 | wake = 0; 362 | /* Order is important. */ 363 | atomic_set(&threadpool->have_scheduled_back); 364 | threadpool_enqueue(&threadpool->scheduled_back, item); 365 | pthread_mutex_unlock(&threadpool->lock); 366 | 367 | if(wake && threadpool->wakeup) 368 | threadpool->wakeup(threadpool->wakeup_closure); 369 | 370 | return 0; 371 | } 372 | 373 | void 374 | threadpool_run_callbacks(threadpool_t *threadpool) 375 | { 376 | threadpool_item_t *items; 377 | 378 | if(!atomic_test(&threadpool->have_scheduled_back)) 379 | return; 380 | 381 | pthread_mutex_lock(&threadpool->lock); 382 | items = threadpool->scheduled_back.first; 383 | /* Order is important. */ 384 | threadpool->scheduled_back.first = NULL; 385 | threadpool->scheduled_back.last = NULL; 386 | atomic_reset(&threadpool->have_scheduled_back); 387 | pthread_mutex_unlock(&threadpool->lock); 388 | 389 | while(items) { 390 | threadpool_item_t *first; 391 | threadpool_func_t *func; 392 | void *closure; 393 | first = items; 394 | items = items->next; 395 | func = first->func; 396 | closure = first->closure; 397 | free(first); 398 | func(closure); 399 | } 400 | } 401 | -------------------------------------------------------------------------------- /threadpool.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2009 by Juliusz Chroboczek 3 | 4 | Permission is hereby granted, free of charge, to any person obtaining a copy 5 | of this software and associated documentation files (the "Software"), to deal 6 | in the Software without restriction, including without limitation the rights 7 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | copies of the Software, and to permit persons to whom the Software is 9 | furnished to do so, subject to the following conditions: 10 | 11 | The above copyright notice and this permission notice shall be included in 12 | all copies or substantial portions of the Software. 13 | 14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 20 | THE SOFTWARE. 21 | */ 22 | 23 | typedef void (threadpool_func_t)(void*); 24 | 25 | typedef struct threadpool threadpool_t; 26 | 27 | /* Create a new thread pool. The wake up callback will be called often 28 | enough to make sure that the caller can flush the callback queue. */ 29 | threadpool_t *threadpool_create(int maxthreads, 30 | threadpool_func_t *wakeup, 31 | void *wakeup_closure); 32 | 33 | /* Cause a thread pool to die. Returns whenever there is new stuff in the 34 | callback queue, or immediately if canblock is false. Returns true when 35 | the thread pool is dead. */ 36 | int threadpool_die(threadpool_t *threadpool, int canblock); 37 | 38 | /* Destroy a thread pool. Does nothing and returns -1 if the pool is not 39 | dead. */ 40 | int threadpool_destroy(threadpool_t *threadpool); 41 | 42 | /* Schedule a new piece of work for a thread pool. Returns -1 if something 43 | went wrong. */ 44 | int threadpool_schedule(threadpool_t *threadpool, 45 | threadpool_func_t *func, void *closure); 46 | 47 | /* Schedule a callback for the main loop. This may be called by any 48 | thread, not only one that belongs to the thread pool. */ 49 | int threadpool_schedule_back(threadpool_t *threadpool, 50 | threadpool_func_t *func, void *closure); 51 | 52 | /* Execute all queued callbacks. This should be called in a timely 53 | manner after the wakeup function has been called. Calling it more 54 | often than that doesn't harm, the nothing-to-do case is extremely 55 | fast and doesn't take any locks. */ 56 | void threadpool_run_callbacks(threadpool_t *threadpool); 57 | -------------------------------------------------------------------------------- /util.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #if defined(_WIN32) || defined(__CYGWIN__) 8 | #include 9 | #include 10 | #include 11 | #else 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #endif 18 | 19 | #include "util.h" 20 | 21 | #ifndef INADDR_NONE 22 | #define INADDR_NONE 0xffffffff 23 | #endif 24 | #ifndef IN_MULTICAST 25 | #define IN_MULTICAST(i) (((u_int32_t)(i) & 0xf0000000) == 0xe0000000) 26 | #endif 27 | 28 | static struct addrinfo *util_getaddrinfo(const char *node, const char *serv, 29 | int flags) 30 | { 31 | struct addrinfo hints, *result; 32 | 33 | memset(&hints, 0, sizeof(struct addrinfo)); 34 | hints.ai_family = AF_UNSPEC; 35 | hints.ai_socktype = SOCK_STREAM; 36 | hints.ai_flags = flags; 37 | 38 | int ret = getaddrinfo(node, serv, &hints, &result); 39 | if (ret) { 40 | fprintf(stderr, "getaddrinfo() failed: %s\n", gai_strerror(ret)); 41 | return NULL; 42 | } 43 | 44 | return result; 45 | } 46 | 47 | static int util_inet_ntop(int family, struct sockaddr *sa, char *buf, 48 | size_t blen) 49 | { 50 | struct sockaddr_in *sin; 51 | struct sockaddr_in6 *sin6; 52 | #if defined(_WIN32) || defined (__CYGWIN__) 53 | void *src; 54 | #else 55 | const void *src; 56 | #endif 57 | 58 | if (family == AF_INET) { 59 | sin = (struct sockaddr_in *)sa; 60 | src = &sin->sin_addr; 61 | } else if (family == AF_INET6) { 62 | sin6 = (struct sockaddr_in6 *)sa; 63 | src = &sin6->sin6_addr; 64 | } else { 65 | fprintf(stderr, "invalid address family %d\n", family); 66 | return -1; 67 | } 68 | 69 | if (!inet_ntop(family, src, buf, blen)) { 70 | perror("inet_ntop"); 71 | return -1; 72 | } 73 | 74 | return 0; 75 | } 76 | 77 | int util_my_ip_address(char *buf, size_t buflen, int all) 78 | { 79 | int ret = -1; 80 | char tmp[INET6_ADDRSTRLEN + 1]; 81 | #if defined(_WIN32) || defined(__CYGWIN__) 82 | PIP_ADAPTER_ADDRESSES pAdapterAddresses = NULL, pInfo = NULL; 83 | ULONG ulBufferLength = 0; 84 | DWORD dwRet; 85 | PIP_ADAPTER_UNICAST_ADDRESS pUniAddr; 86 | 87 | buf[0] = '\0'; 88 | 89 | do { 90 | dwRet = GetAdaptersAddresses(AF_UNSPEC, GAA_FLAG_INCLUDE_PREFIX, NULL, 91 | pAdapterAddresses, &ulBufferLength); 92 | if (dwRet == ERROR_BUFFER_OVERFLOW) { 93 | if (pAdapterAddresses) 94 | free(pAdapterAddresses); 95 | pAdapterAddresses = malloc(ulBufferLength); 96 | if (!pAdapterAddresses) { 97 | return -1; 98 | } 99 | } 100 | } while (dwRet == ERROR_BUFFER_OVERFLOW); 101 | 102 | if (dwRet != ERROR_SUCCESS && dwRet != ERROR_NO_DATA) { 103 | if (pAdapterAddresses) 104 | free(pAdapterAddresses); 105 | return -1; 106 | } 107 | 108 | int break_out = 0; 109 | for (pInfo = pAdapterAddresses; pInfo; pInfo = pInfo->Next) { 110 | for (pUniAddr = pInfo->FirstUnicastAddress; pUniAddr; 111 | pUniAddr = pUniAddr->Next) { 112 | DWORD dwLen = sizeof(tmp); 113 | int rc = WSAAddressToString(pUniAddr->Address.lpSockaddr, 114 | pUniAddr->Address.iSockaddrLength, 115 | NULL, (LPTSTR)tmp, &dwLen); 116 | if (rc) 117 | continue; 118 | 119 | char *percent = strchr(tmp, '%'); 120 | if (percent) 121 | *percent = '\0'; 122 | 123 | /* First check if there's enough space in buf. */ 124 | if (strlen(tmp) + strlen(buf) + 2 > buflen) { 125 | /* Buffer too small. Try next address and see if it fits. */ 126 | continue; 127 | } 128 | 129 | /* There's enough space to hold the address plus the semicolon. */ 130 | if (strlen(buf) > 0) 131 | strcat(buf, ";"); 132 | strcat(buf, tmp); 133 | 134 | ret = 0; 135 | 136 | if (!all) { 137 | break_out = 1; 138 | break; 139 | } 140 | } 141 | 142 | if (break_out) 143 | break; 144 | } 145 | 146 | free(pAdapterAddresses); 147 | #else 148 | struct ifaddrs *addrs, *a; 149 | struct sockaddr_in *sin; 150 | struct sockaddr_in6 *sin6; 151 | uint32_t x; 152 | 153 | buf[0] = '\0'; 154 | 155 | if (getifaddrs(&addrs)) { 156 | perror("getifaddrs() failed"); 157 | return -1; 158 | } 159 | 160 | for (a = addrs; a; a = a->ifa_next) { 161 | if (!a->ifa_addr) 162 | continue; 163 | 164 | if (a->ifa_addr->sa_family == AF_INET) { 165 | sin = (struct sockaddr_in *)a->ifa_addr; 166 | x = ntohl(sin->sin_addr.s_addr); 167 | if (IN_MULTICAST(x) || 168 | INADDR_ANY == x || 169 | INADDR_NONE == x || 170 | ((x & 0xff000000) == 0x7f000000) || 171 | (((x & 0xff000000) == 0xa9000000) && 172 | ((x & 0x00ff0000) == 0x00fe0000))) { 173 | continue; 174 | } 175 | 176 | if (util_inet_ntop(sin->sin_family, a->ifa_addr, tmp, 177 | sizeof(tmp))) { 178 | break; 179 | } 180 | } else if (a->ifa_addr->sa_family == AF_INET6) { 181 | sin6 = (struct sockaddr_in6 *)a->ifa_addr; 182 | if (IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr) || 183 | IN6_IS_ADDR_LOOPBACK(&sin6->sin6_addr) || 184 | IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr) || 185 | IN6_IS_ADDR_SITELOCAL(&sin6->sin6_addr) || 186 | IN6_IS_ADDR_MULTICAST(&sin6->sin6_addr)) { 187 | continue; 188 | } 189 | 190 | if (util_inet_ntop(sin6->sin6_family, a->ifa_addr, tmp, 191 | sizeof(tmp))) { 192 | break; 193 | } 194 | } else { 195 | continue; 196 | } 197 | 198 | if (strlen(tmp) + strlen(buf) + 2 > buflen) 199 | break; 200 | 201 | if (buf[0] != '\0') 202 | strcat(buf, ";"); 203 | strcat(buf, tmp); 204 | 205 | ret = 0; 206 | 207 | if (!all) 208 | break; 209 | } 210 | 211 | if (addrs) 212 | freeifaddrs(addrs); 213 | #endif 214 | 215 | return ret; 216 | } 217 | 218 | int util_dns_resolve(const char *host, char *buf, size_t buflen, int all) 219 | { 220 | int ret = -1; 221 | char tmp[INET6_ADDRSTRLEN + 1]; 222 | struct addrinfo *addrs = util_getaddrinfo(host, NULL, 0), *a; 223 | 224 | buf[0] = '\0'; 225 | 226 | if (!addrs) 227 | goto out; 228 | 229 | for (a = addrs; a; a = a->ai_next) { 230 | if (util_inet_ntop(a->ai_family, a->ai_addr, tmp, sizeof(tmp))) { 231 | perror("inet_ntop"); 232 | goto out; 233 | } 234 | 235 | if (strlen(tmp) + strlen(buf) + 2 > buflen) 236 | break; 237 | 238 | if (buf[0] != '\0') 239 | strcat(buf, ";"); 240 | strcat(buf, tmp); 241 | 242 | ret = 0; 243 | 244 | if (!all) 245 | break; 246 | } 247 | 248 | out: 249 | if (addrs) 250 | freeaddrinfo(addrs); 251 | return ret; 252 | } 253 | 254 | -------------------------------------------------------------------------------- /util.h: -------------------------------------------------------------------------------- 1 | #define UTIL_BUFLEN 64 2 | 3 | int util_dns_resolve(const char *host, char *buf, size_t buflen, int all); 4 | int util_my_ip_address(char *buf, size_t buflen, int all); 5 | --------------------------------------------------------------------------------