我一直在尝试使用 store-id-program 设置在 Windows 机器上安装 squid 3.5.27。
然而,似乎无论我如何设置,我正在运行的 python 脚本都会立即得到输入结束(可以通过添加跟踪看到),然后 squid 停止运行,并抱怨
Squid Cache (Version 3.5.27): Terminated abnormally.
FATAL: The store_id helpers are crashing too rapidly, need help!
我尝试过各种各样的变体(显然不是同时尝试的):
store_id_program /cygdrive/c/apps/squid/local/bin/texture_rewrite.bat
store_id_program /cygdrive/c/apps/squid/local/bin/texture_rewrite.py
store_id_program /cygdrive/c/apps/Python27/python.exe -u c:\apps\squid\local\bin\texture_rewrite.py
(.bat 文件由以下内容组成@<path-to-python> -u <path to script>
)
如果我不尝试设置 URL 重写,Squid 可以正常工作。
作为参考,python 脚本如下所示:
while True:
line = sys.stdin.readline()
print >>sys.stderr, line
if not line:
break
line = line.strip()
if line != '':
process(line)
print >>sys.stderr, 'exit'
进程(line)永远不会被调用
答案1
如果你引用的是我们的 Squid for windows 版本squid.diladele.com- 那么这很可能是由于 Cygwin 如何对 Cygwin 二进制文件 (squid) 和本机 Windows 二进制文件 (python) 之间的管道进行建模。如果我没有记错的话,管道被建模为文件上的非阻塞重叠 IO - 在读取后立即出现 ERROR_IO_PENDING - 在任何控制台程序中都被解释为 EOF。
这个问题的部分讨论https://www.cygwin.com/ml/cygwin/2006-03/msg00330.html,https://github.com/nodejs/node/issues/3006以及其他许多人。
最好的办法是将 urlrewriter 编译为 C++ 代码从 cygwin 内部- 在这种情况下,代码将自动使用与 squid 相同的管道实现,从而正常工作。或者像我们在 urlrewriter 中所做的那样,从重叠文件中逐字节读取(仅作为示例)
read_result read(char& c)
{
// this is the value to return
CHAR value = 0;
DWORD read = 0;
DWORD len = sizeof(CHAR);
// construct overlapped structure
OVERLAPPED ovl = {};
{
ovl.hEvent = hevent_;
}
// read one byte from input
BOOL bres = ::ReadFile(stdin_, &value, len, &read, &ovl);
DWORD err = ::GetLastError();
if (bres)
{
// see if we read 0 bytes
if (0 == read)
{
// yes, read of 0 bytes from the redirected pipe in cygwin means eof???
return reached_eof;
}
// debug check
_ASSERTE('\0' != value);
// otherwise store char
c = value;
// nice
return read_success;
}
// we have encountered and error, see which one
switch (err)
{
case ERROR_HANDLE_EOF:
return reached_eof;
case ERROR_IO_PENDING:
{
// wait until overlapped read completes
BOOL bres = GetOverlappedResult(stdin_, &ovl, &read, TRUE);
if (bres)
{
// good, we have read one byte
c = value;
// nice
return read_success;
}
// overlapped result failed, there might be a lot of reason for this, see if EOF is there
if (ERROR_HANDLE_EOF == GetLastError())
return reached_eof;
// in case of all other errors we fail the operation
return read_error;
}
break;
default:
// some unknown error, we also fail the operation
return read_error;
}
}