use Pythons builtin HTTPS support

git-svn-id: https://linkchecker.svn.sourceforge.net/svnroot/linkchecker/trunk/linkchecker@317 e7d03fd6-7b0d-0410-9947-9c21f3af8025
This commit is contained in:
calvin 2001-11-20 20:27:25 +00:00
parent 3f18aafa43
commit d54f2ba8da
13 changed files with 58 additions and 694 deletions

6
debian/changelog vendored
View file

@ -1,3 +1,9 @@
linkchecker (1.3.10) unstable; urgency=low
* use Pythons builtin HTTPS support
-- Bastian Kleineidam <calvin@debian.org> Tue, 20 Nov 2001 21:24:28 +0100
linkchecker (1.3.9) unstable; urgency=low
* new config option --interactive for interactive URL input

10
debian/control vendored
View file

@ -3,13 +3,13 @@ Section: web
Priority: optional
Maintainer: Bastian Kleineidam <calvin@debian.org>
Build-Depends-Indep: python-dev (>= 2.1), python-dev (<< 2.2), debhelper (>= 3.0.0), gettext
Standards-Version: 3.5.6
Standards-Version: 3.5.6.0
Package: linkchecker
Architecture: all
Architecture: any
Depends: python (>= 2.1)
Conflicts: python (>= 2.2)
Suggests: linkchecker-ssl
Conflicts: python (>= 2.2), python-ssl (>= 2.2)
Suggests: python-ssl (>= 2.1)
Description: check HTML documents for broken links
Features:
o recursive checking
@ -25,3 +25,5 @@ Description: check HTML documents for broken links
o i18n support
o command line interface
o (Fast)CGI web interface (requires HTTP server)
You have to install python-ssl for HTTPS support.

View file

@ -1,32 +0,0 @@
#!/bin/sh -e
#
# Written 1998 by Gregor Hoffleit <flight@debian.org>.
# used by Bastian Kleineidam for LinkChecker
PYTHON=python2.1
FILELIST=
SITEPACKAGES=/usr/lib/$PYTHON/site-packages
DIRLIST=linkcheckssl
COMMAND="'import sys,py_compile;py_compile.compile(sys.argv[1])'"
case "$1" in
configure|abort-upgrade|abort-remove|abort-deconfigure)
for i in $DIRLIST; do
$PYTHON -O /usr/lib/$PYTHON/compileall.py -q $SITEPACKAGES/$i
$PYTHON /usr/lib/$PYTHON/compileall.py -q $SITEPACKAGES/$i
done
# use /bin/sh -c, otherwise I get a SyntaxError from Python
for i in $FILELIST; do
/bin/sh -c "$PYTHON -O -c $COMMAND $SITEPACKAGES/$i"
/bin/sh -c "$PYTHON -c $COMMAND $SITEPACKAGES/$i"
done
;;
*)
echo "postinst called with unknown argument \`$1'" >&2
exit 1
;;
esac
#DEBHELPER#
exit 0

View file

@ -1,17 +0,0 @@
#!/bin/sh -e
#
# Written 1998 by Gregor Hoffleit <flight@debian.org>.
# used by Bastian Kleineidam for LinkChecker
PYTHON=python2.1
PACKAGE=linkchecker-ssl
#DEBHELPER#
dpkg --listfiles $PACKAGE |
awk '$0~/\.py$/ {print $0"c\n" $0"o"}' |
xargs rm -f >&2
rmdir /usr/lib/$PYTHON/site-packages/linkcheckssl 2>/dev/null || true
exit 0

5
debian/rules vendored
View file

@ -17,14 +17,13 @@ export DH_OPTIONS
configure: configure-stamp
configure-stamp:
dh_testdir
$(PYTHON) setup.py config -lcrypto
$(PYTHON) setup.py config
touch configure-stamp
build: configure-stamp build-stamp
build-stamp:
dh_testdir
rm -rf debian/linkchecker debian/linkchecker-ssl
$(PYTHON) setup.py build
touch build-stamp
@ -44,8 +43,6 @@ install: build
rm -r debian/$(PACKAGE)/usr/man
# remove files, we install them below
rm -r debian/$(PACKAGE)/usr/share/linkchecker/examples
# remove any SSL related files
rm -r debian/$(PACKAGE)/usr/lib/$(PYTHON)/site-packages/linkcheckssl
# install additional doc files
install -c -m 644 DNS/README $(DOCDIR)/README_DNS.txt
install -c -m 644 test/*.py $(DOCDIR)/test

View file

@ -15,10 +15,13 @@
# along with this program; if not, write to the Free Software
# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
import re,string,os,urlparse,urllib
from UrlData import UrlData
import re, os, urlparse, urllib
from UrlData import UrlData, ExcList
from linkcheck import _
# OSError is thrown on Windows when a file is not found
ExcList.append(OSError)
html_re = re.compile(r'(?i)\.s?html?$')
html_content_re = re.compile(r'(?i)<html>.*</html>')
opera_re = re.compile(r'^(?i)opera.adr$')
@ -48,7 +51,7 @@ class FileUrlData(UrlData):
self.urlName = os.getcwd()+"/"+self.urlName
if winre.search(self.urlName):
self.adjustWinPath()
self.urlName = string.replace(self.urlName, "\\", "/")
self.urlName = self.urlName.replace("\\", "/")
self.urlName = "file://"+self.urlName

View file

@ -15,8 +15,8 @@
# along with this program; if not, write to the Free Software
# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
import httplib,urlparse,sys,time,re
import Config,StringUtil,robotparser2
import httplib, urlparse, sys, time, re
import Config, StringUtil, robotparser2
from UrlData import UrlData
from urllib import splittype, splithost, splituser, splitpasswd
from linkcheck import _
@ -223,7 +223,10 @@ class HttpUrlData(UrlData):
return self.urlConnection.getreply()
def _getHTTPObject(self, host):
return httplib.HTTP(host)
h = httplib.HTTP()
h.set_debuglevel(Config.DebugLevel)
h.connect(host)
return h
def getContent(self):
if not self.has_content:

View file

@ -17,19 +17,16 @@
from UrlData import UrlData
from HttpUrlData import HttpUrlData
from linkcheck import _
_supportHttps=1
try:
from linkcheckssl import httpslib
except ImportError:
_supportHttps=0
from linkcheck import _, Config
_supportHttps = hasattr(httplib, "HTTPS")
class HttpsUrlData(HttpUrlData):
"""Url link with https scheme"""
def _getHTTPObject(self, host):
h = httpslib.HTTPS()
h = httplib.HTTPS()
h.set_debuglevel(Config.DebugLevel)
h.connect(host)
return h

View file

@ -15,10 +15,10 @@
# along with this program; if not, write to the Free Software
# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
import sys,re,string,urlparse,urllib,time,DNS
import Config,StringUtil,linkcheck,linkname
import sys, re, urlparse, urllib, time, DNS, traceback
import Config, StringUtil, linkcheck, linkname
debug = Config.debug
from linkcheck import _
debug = linkcheck.Config.debug
from debuglevels import *
# we catch these exceptions, all other exceptions are internal
@ -43,7 +43,7 @@ _linkMatcher = r"""
\s* # whitespace
%s # tag name
\s+ # whitespace
[^>]*? # skip leading attributes
[^>]*? # skip leading attributes (fails on Python 2.2b2)
%s # attrib name
\s* # whitespace
= # equal sign
@ -108,8 +108,7 @@ BasePattern = {
'attr': 'href',
}
CommentPattern = re.compile("<!--.*?--\s*>", re.DOTALL)
#CommentPattern = re.compile("<!--.*?--\s*>", re.DOTALL)
# Workaround for Python 2.0 re module bug
CommentPatternBegin = re.compile("<!--")
CommentPatternEnd = re.compile("--\s*>")
@ -189,8 +188,8 @@ class UrlData:
self.url = self.urlName
self.urlTuple = urlparse.urlparse(self.url)
# make host lowercase
self.urlTuple = (self.urlTuple[0],string.lower(self.urlTuple[1]),
self.urlTuple[2],self.urlTuple[3],self.urlTuple[4],
self.urlTuple = (self.urlTuple[0], self.urlTuple[1].lower(),
self.urlTuple[2], self.urlTuple[ 3],self.urlTuple[4],
self.urlTuple[5])
self.url = urlparse.urlunparse(self.urlTuple)
# resolve HTML entities
@ -221,7 +220,8 @@ class UrlData:
self.buildUrl()
self.extern = self._getExtern(config)
except tuple(ExcList):
type, value = sys.exc_info()[:2]
type, value, tb = sys.exc_info()
debug(HURT_ME_PLENTY, "exception", traceback.format_tb(tb))
self.setError(str(value))
self.logMe(config)
return
@ -248,8 +248,8 @@ class UrlData:
if self.urlTuple and config["anchors"]:
self.checkAnchors(self.urlTuple[5])
except tuple(ExcList):
type, value = sys.exc_info()[:2]
#print type, value
type, value, tb = sys.exc_info()
debug(HURT_ME_PLENTY, "exception", traceback.format_tb(tb))
self.setError(str(value))
# check content
@ -258,7 +258,8 @@ class UrlData:
debug(BRING_IT_ON, "checking content")
try: self.checkContent(warningregex)
except tuple(ExcList):
type, value = sys.exc_info()[:2]
type, value, tb = sys.exc_info()
debug(HURT_ME_PLENTY, "exception", traceback.format_tb(tb))
self.setError(str(value))
self.checktime = time.time() - t
@ -417,7 +418,7 @@ class UrlData:
index = match.end()
if self.is_in_comment(match.start()): continue
# need to strip optional ending quotes for the meta tag
url = string.strip(StringUtil.stripQuotes(match.group('value')))
url = StringUtil.stripQuotes(match.group('value')).strip()
# need to resolve HTML entities
url = StringUtil.unhtmlify(url)
lineno=StringUtil.getLineNumber(self.getContent(), match.start())
@ -480,11 +481,11 @@ def GetUrlDataFrom(urlName, recursionLevel, parentName = None,
# search for the absolute url
url=""
if urlName and ":" in urlName:
url = string.lower(urlName)
url = urlName.lower()
elif baseRef and ":" in baseRef:
url = string.lower(baseRef)
url = baseRef.lower()
elif parentName and ":" in parentName:
url = string.lower(parentName)
url = parentName.lower()
# test scheme
if re.search("^http:", url):
klass = HttpUrlData

View file

@ -1 +0,0 @@
"""ssl wrapper module"""

View file

@ -1,175 +0,0 @@
# @(#)httpslib.py 1.1 VMS-99/01/30 https support
import ssl,httplib,string,socket,mimetools
HTTP_PREF = 'HTTP/'
HTTPS_PORT = 443
class HTTPS(httplib.HTTP):
def connect (self, host, port = 0):
"""Connect to a host on a given port.
Note: This method is automatically invoked by __init__,
if a host is specified during instantiation.
"""
if not port:
i = string.find(host, ':')
if i >= 0:
host, port = host[:i], host[i+1:]
try: port = string.atoi(port)
except string.atoi_error:
raise socket.error, "nonnumeric port"
if not port: port = HTTPS_PORT
self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
if self.debuglevel > 0: print 'connect:', (host, port)
self.sock.connect((host, port))
self.ssl = ssl.ssl(self.sock.fileno())
def send (self, str):
if self.debuglevel > 0: print 'send:', `str`
self.ssl.write(str,len(str))
def makefile (self, mode='r', bufsize=-1):
return _fileobject(self.sock,self.ssl,mode,bufsize)
def getreply (self):
self.file = self.makefile('rb')
# self.sock = None
line = self.file.readline()
if self.debuglevel > 0: print 'reply:',`line`
try:
[ver,code,msg] = string.split(line,None,2)
except ValueError:
try:
[ver,code] = string.split(line,None,1)
msg = ""
except ValueError:
ver = ""
if ver[:len(HTTP_PREF)] != HTTP_PREF:
self.headers = None
return -1, line, self.headers
self.headers = mimetools.Message(self.file,0)
return string.atoi(code), string.strip(msg), self.headers
def close (self):
if self.file:
self.file.close()
self.file = self.sock = self.ssl = None
class _fileobject:
def __init__ (self, sock, ssl, mode, bufsize):
import string
self._sock = sock
self._ssl = ssl
self._mode = mode
if bufsize < 0:
bufsize = 512
self._rbufsize = max(1,bufsize)
self._wbufsize = bufsize
self._wbuf = self._rbuf = ""
def close (self):
try:
if self._sock:
self.flush()
finally:
self._sock = None
def __del__ (self):
self.close()
def flush (self):
if self._wbuf:
self._sock.write(self._wbuf,len(self._wbuf))
self._wbuf = ""
def fileno (self):
return self._sock.fileno()
def write (self, data):
self._wbuf += data
if self._wbufsize == 1:
if '\n' in data:
self.flush()
else:
if len(self._wbuf) >= self._wbufsize:
self.flush()
def writelines (self, lst):
filter(self._sock.send,lst)
self.flush()
def read (self, n=-1):
if n >= 0:
while len(self._rbuf) < n:
new = self._ssl.read(self._rbufsize)
if not new: break
self._rbuf += new
data,self._rbuf = self._rbuf[:n],self._rbuf[n:]
return data
while 1:
new = self._ssl.read(self._rbufsize)
if not new: break
self._rbuf += new
data,self._rbuf = self._rbuf,""
return data
def readline (self):
data = ""
i = string.find(self._rbuf,'\n')
while i < 0:
new = self._ssl.read(self._rbufsize)
if not new: break
i = string.find(new,'\n')
if i >= 0:
i += len(self._rbuf)
self._rbuf += new
if i < 0:
i = len(self._rbuf)
else:
i += 1
data,self._rbuf = self._rbuf[:i],self._rbuf[i:]
return data
def readlines (self):
l = []
while 1:
line = self.readline()
if not line: break
l.append(line)
return l
def _test():
import sys
import getopt
opts, args = getopt.getopt(sys.argv[1:], 'd')
dl = 0
for o, a in opts:
if o == '-d':
dl += 1
if args[0:]:
host = args[0]
if args[1:]:
selector = args[1]
h = HTTPS()
host = 'synergy.as.cmu.edu'
selector = '/~geek/'
h.set_debuglevel(dl)
h.connect(host)
h.putrequest('GET', selector)
h.endheaders()
errcode, errmsg, headers = h.getreply()
print 'errcode =', errcode
print 'errmsg =', errmsg
print "\tHEADERS:"
if headers:
for header in headers.headers:
print string.strip(header)
print "\tTEXT:"
print h.getfile().read()
if __name__ == '__main__':
_test()

View file

@ -1,356 +0,0 @@
/* @(#)ssl.c 1.1 VMS-99/01/30 python wrapper for SSLeay https
*/
#include "Python.h"
#include <sys/types.h>
#ifndef MS_WINDOWS
#include <sys/socket.h>
#else
#include <winsock.h>
#endif
#if defined(PYOS_OS2)
#define INCL_DOS
#define INCL_DOSERRORS
#define INCL_NOPMAPI
#include <os2.h>
#endif
#include "ssl.h"
#include "err.h"
/* Global variable holding the exception type for errors detected
by this module (but not argument type or memory errors, etc.). */
static PyObject *PySslError;
typedef struct {
PyObject_HEAD
int sock_fd;
PyObject *x_attr; /* attributes dictionary */
SSL_CTX *ctx;
SSL *ssl;
X509 *server_cert;
BIO *sbio;
char server[256];
char issuer[256];
} PySslObject;
staticforward PyTypeObject SSL_Type;
#define PySslObject_Check(v) ((v)->ob_type == &SSL_Type)
#define PY_SSL_ERR_MAX 256
/*
* raise an error according to errno, return NULL
*/
static PyObject* PySsl_errno (void) {
#ifdef MS_WINDOWS
if (WSAGetLastError()) {
PyObject *v = Py_BuildValue("(is)",WSAGetLastError(),"winsock error");
if (v) {
PyErr_SetObject(PySslError,v);
Py_DECREF(v);
}
return NULL;
}
#endif
return PyErr_SetFromErrno(PySslError);
}
/*
* format SSl error string
*/
static int PySsl_err_str (unsigned long e, char* buf) {
unsigned long l = ERR_GET_LIB(e);
unsigned long f = ERR_GET_FUNC(e);
unsigned long r = ERR_GET_REASON(e);
char* ls = (char*)ERR_lib_error_string(e);
char* fs = (char*)ERR_func_error_string(e);
char* rs = (char*)ERR_reason_error_string(e);
char* bp = buf + 2; /* skip two initial blanks */
(void)strcpy(buf," none:"); /* initialize buffer */
bp += (ls) ? sprintf(bp,"%s:",ls) :
((l) ? sprintf(bp,"lib %lu:",l) : 0);
bp += (fs) ? sprintf(bp,"%s ",fs) :
((f) ? sprintf(bp,"func %lu:",f) : 0);
bp += (rs) ? sprintf(bp,"%s:",rs) :
((r) ? sprintf(bp,"reason(%lu):",r) : 0);
*bp-- = 0; /* suppress last divider (:) */
return (bp - buf);
}
/*
* report SSL core errors
*/
static PySslObject* PySsl_errors (void) {
unsigned long e;
char buf[2 * PY_SSL_ERR_MAX];
char *bf = buf;
while (((bf - buf) < PY_SSL_ERR_MAX) && (e = ERR_get_error()))
bf += PySsl_err_str(e,bf);
{
PyObject *v = Py_BuildValue("(sss)", "ssl","core",buf+2);
if (v != NULL) {
PyErr_SetObject(PySslError,v);
Py_DECREF(v);
}
}
return (NULL);
}
/*
* report SSL application layer errors
*/
static PySslObject* PySsl_app_errors (SSL* s, int ret) {
int err = SSL_get_error(s,ret);
char *str;
switch (err) {
case SSL_ERROR_SSL:
return (PySsl_errors());
case SSL_ERROR_SYSCALL:
return ((PySslObject *)PySsl_errno());
case SSL_ERROR_ZERO_RETURN:
str = "End of data";
break;
case SSL_ERROR_WANT_READ:
str = "Want read";
break;
case SSL_ERROR_WANT_WRITE:
str = "Want write";
break;
case SSL_ERROR_WANT_X509_LOOKUP:
str = "Want x509 lookup";
break;
case SSL_ERROR_WANT_CONNECT:
str = "Want connect";
break;
default:
str = "Unknown";
break;
}
{
PyObject *v = Py_BuildValue("(sis)", "ssl",err, str);
if (v != NULL) {
PyErr_SetObject(PySslError,v);
Py_DECREF(v);
}
}
return (NULL);
}
/* ssl.read(len) method */
static PyObject* PySslObj_read (PySslObject* self, PyObject* args) {
int len, n;
PyObject *buf;
if (!PyArg_ParseTuple(args,"i",&len))
return (NULL);
if (!(buf = PyString_FromStringAndSize((char *)0,len)))
return (NULL);
Py_BEGIN_ALLOW_THREADS
n = SSL_read(self->ssl,PyString_AsString(buf),len);
Py_END_ALLOW_THREADS
switch (SSL_get_error(self->ssl,n)) {
case SSL_ERROR_NONE: /* good return value */
break;
case SSL_ERROR_ZERO_RETURN:
case SSL_ERROR_SYSCALL:
if (!n) /* fix SSL_ERROR_SYCSALL errno=0 case */
break;
/* fall thru here */
default:
Py_DECREF(buf);
(void)PySsl_app_errors(self->ssl,n);
return (NULL);
}
if ((n != len) && (_PyString_Resize(&buf,n) < 0))
return (NULL);
return (buf);
}
/* ssl.write(data,len) method */
static PyObject* PySslObj_write (PySslObject* self, PyObject * args) {
char *buf;
int len, n;
if (!PyArg_ParseTuple(args, "si", &buf, &len))
return NULL;
/* Note: flags are ignored */
Py_BEGIN_ALLOW_THREADS
n = SSL_write(self->ssl,buf,len);
Py_END_ALLOW_THREADS
if (n < 0)
return (PySsl_errno());
return (PyInt_FromLong((long)n));
}
/* ssl.server() method */
static PyObject* PySslObj_server (PySslObject* self, PyObject* args) {
if (!PyArg_NoArgs(args))
return (NULL);
return (PyString_FromString(self->server));
}
/* ssl.issuer() method */
static PyObject* PySslObj_issuer (PySslObject* self, PyObject* args) {
if (!PyArg_NoArgs(args))
return (NULL);
return (PyString_FromString(self->issuer));
}
/* SSL object methods */
static PyMethodDef PySslObj_methods[] = {
{"read", (PyCFunction)PySslObj_read,1},
{"write", (PyCFunction)PySslObj_write,1},
{"server", (PyCFunction)PySslObj_server},
{"issuer", (PyCFunction)PySslObj_issuer},
{ NULL, NULL}
};
static void PySsl_dealloc (PySslObject * self) {
if (self->server_cert) /* possible not to have one? */
X509_free(self->server_cert);
SSL_CTX_free(self->ctx);
SSL_free(self->ssl);
Py_XDECREF(self->x_attr);
PyMem_DEL(self);
}
static PyObject* PySsl_getattr (PySslObject* self, char * name) {
return (Py_FindMethod(PySslObj_methods,(PyObject *)self,name));
}
staticforward PyTypeObject SSL_Type = {
PyObject_HEAD_INIT(&PyType_Type)
0, /*ob_size*/
"SSL", /*tp_name*/
sizeof(PySslObject), /*tp_basicsize*/
0, /*tp_itemsize*/
/* methods */
(destructor)PySsl_dealloc, /*tp_dealloc*/
0, /*tp_print*/
(getattrfunc)PySsl_getattr, /*tp_getattr*/
0, /*tp_setattr*/
0, /*tp_compare*/
0, /*tp_repr*/
0, /*tp_as_number*/
0, /*tp_as_sequence*/
0, /*tp_as_mapping*/
0, /*tp_hash*/
};
/*
* C function called for new object initialization
* Note: SSL protocol version 2, 3, or 2+3 set at compile time
*/
static PySslObject* newPySslObject (int sock_fd) {
PySslObject *self;
SSL_METHOD *meth;
int ret;
#if 0
meth=SSLv3_client_method();
meth=SSLv23_client_method();
#endif
meth=SSLv2_client_method();
if (!(self = PyObject_NEW(PySslObject,&SSL_Type))) /* create new object */
return (NULL);
(void)memset(self->server,0,sizeof(self->server));
(void)memset(self->issuer,0,sizeof(self->issuer));
self->x_attr = PyDict_New();
if (!(self->ctx = SSL_CTX_new(meth))) { /* set up context */
PyMem_DEL(self);
return (PySsl_errors());
}
#if 0 /* Note: set this for v23, Netscape server */
SSL_CTX_set_options(self->ctx,SSL_OP_ALL);
#endif
self->ssl = SSL_new(self->ctx); /* new ssl struct */
if (!(ret = SSL_set_fd(self->ssl,sock_fd))) { /* set the socket for SSL */
PyMem_DEL(self);
return (PySsl_app_errors(self->ssl,ret));
}
SSL_CTX_set_verify(self->ctx,SSL_VERIFY_NONE,NULL); /* set verify lvl */
SSL_set_connect_state(self->ssl);
if ((ret = SSL_connect(self->ssl)) < 0) { /* negotiate SSL connection */
PyMem_DEL(self);
return (PySsl_app_errors(self->ssl,ret));
}
self->ssl->debug = 1;
if ((self->server_cert = SSL_get_peer_certificate(self->ssl))) {
X509_NAME_oneline(X509_get_subject_name(self->server_cert),
self->server,sizeof(self->server));
X509_NAME_oneline(X509_get_issuer_name(self->server_cert),
self->issuer, sizeof(self->issuer));
}
self->x_attr = NULL;
self->sock_fd = sock_fd;
return (self);
}
/*
* Python function called for new object initialization
*/
static PyObject* PySsl_ssl_new (PyObject* self, PyObject* args) {
int sock_fd;
if (!PyArg_ParseTuple(args, "i", &sock_fd))
return (NULL);
return ((PyObject *)newPySslObject(sock_fd));
}
/* List of functions exported by this module. */
static PyMethodDef PySsl_methods[] = {
{"ssl", (PyCFunction)PySsl_ssl_new, METH_VARARGS},
{NULL, NULL} /* sentinel */
};
/*
* Initialize this module, called when the first 'import ssl' is done
*/
void
#ifdef WIN32
__declspec(dllexport)
#endif
initssl (void) {
PyObject *m, *d;
m = Py_InitModule("ssl", PySsl_methods);
d = PyModule_GetDict(m);
SSL_load_error_strings();
SSLeay_add_ssl_algorithms();
/* *** Python 1.5 ***
if (!(PySssl_Error = PyErr_NewException("ssl.error",NULL,NULL)))
return;
*/
if (!(PySslError = PyString_FromString("ssl.error")) ||
PyDict_SetItemString(d,"error",PySslError))
Py_FatalError("can't define ssl.error");
if (PyDict_SetItemString(d,"SSLType",(PyObject *)&SSL_Type))
return;
}

View file

@ -82,57 +82,6 @@ class MyInstall(install):
print " %s: %s" % (opt_name, val)
class MyConfig(config):
user_options = config.user_options + [
('ssl-include-dirs=', None,
"directories to search for SSL header files"),
('ssl-library-dirs=', None,
"directories to search for SSL library files"),
]
def initialize_options (self):
config.initialize_options(self)
self.ssl_include_dirs = None
self.ssl_library_dirs = None
def finalize_options(self):
# we have some default include and library directories
# suitable for each platform
config.finalize_options(self)
if self.ssl_include_dirs is None:
if os.name=='posix':
self.ssl_include_dirs = ['/usr/include/openssl',
'/usr/local/include/openssl']
else:
# dont know default incldirs on other platforms
self.ssl_include_dirs = []
if self.ssl_library_dirs is None:
if os.name=='posix':
self.ssl_library_dirs = ['/usr/lib', '/usr/local/lib']
else:
# dont know default libdirs on other platforms
self.ssl_library_dirs = []
def run (self):
# try to compile a test program with SSL
config.run(self)
self.libraries.append('ssl')
have_ssl = self.check_lib("ssl",
library_dirs = self.ssl_library_dirs,
include_dirs = self.ssl_include_dirs,
headers = ["ssl.h"])
# write the result in the configuration file
data = []
data.append("have_ssl = %d" % (have_ssl))
data.append("ssl_library_dirs = %s" % `self.ssl_library_dirs`)
data.append("ssl_include_dirs = %s" % `self.ssl_include_dirs`)
data.append("libraries = %s" % `self.libraries`)
data.append("install_data = %s" % `os.getcwd()`)
self.distribution.create_conf_file(".", data)
class MyDistribution(Distribution):
def __init__(self, attrs=None):
@ -141,34 +90,23 @@ class MyDistribution(Distribution):
def run_commands(self):
if "config" not in self.commands:
self.check_ssl()
cwd = os.getcwd()
data = []
data.append('config_dir = %s' % `os.path.join(cwd, "config")`)
data.append("install_data = %s" % `cwd`)
self.create_conf_file(".", data)
Distribution.run_commands(self)
def check_ssl(self):
if not os.path.exists(self.config_file):
#raise SystemExit, "please run 'python setup.py config'"
self.announce("generating default configuration")
self.run_command('config')
import _linkchecker_configdata
if 'bdist_wininst' in self.commands and os.name != 'nt':
self.announce("bdist_wininst command found on non-Windows "
"platform. Disabling SSL compilation")
elif _linkchecker_configdata.have_ssl:
self.ext_modules = [Extension('linkcheckssl.ssl',
['linkcheckssl/ssl.c'],
include_dirs=_linkchecker_configdata.ssl_include_dirs,
library_dirs=_linkchecker_configdata.ssl_library_dirs,
libraries=_linkchecker_configdata.libraries)]
def create_conf_file(self, directory, data=[]):
data.insert(0, "# this file is automatically created by setup.py")
filename = os.path.join(directory, self.config_file)
# add metadata
metanames = dir(self.metadata) + \
['fullname', 'contact', 'contact_email']
metanames = ("name", "version", "author", "author_email",
"maintainer", "maintainer_email", "url",
"licence", "description", "long_description",
"keywords", "platforms", "fullname", "contact",
"contact_email", "licence", "fullname")
for name in metanames:
method = "get_" + name
cmd = "%s = %s" % (name, `getattr(self.metadata, method)()`)
@ -189,7 +127,7 @@ myname = "Bastian Kleineidam"
myemail = "calvin@users.sourceforge.net"
setup (name = "linkchecker",
version = "1.3.9",
version = "1.3.10",
description = "check HTML documents for broken links",
author = myname,
author_email = myemail,
@ -213,9 +151,7 @@ o a command line interface
o a (Fast)CGI web interface (requires HTTP server)
""",
distclass = MyDistribution,
cmdclass = {'config': MyConfig,
'install': MyInstall,
},
cmdclass = {'install': MyInstall},
packages = ['','DNS','linkcheck','linkcheckssl'],
scripts = ['linkchecker'],
data_files = [('share/locale/de/LC_MESSAGES',