# GopherConnection.py
# $Id: GopherConnection.py,v 1.16 2001/07/14 22:51:57 s2mdalle Exp $
# Written by David Allen <mda@idatar.com>
# Released under the terms of the GNU General Public License
#
# This object handles connections and sending requests to gopher servers.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
#######################################################################
import socket
import re
import utils
from string import *
import GopherResponse
import Connection
import GopherObject
import GopherResource
import ResourceInformation
import AskForm
from gopher import *
GopherConnectionException = "Error: "
class GopherConnection(Connection.Connection):
SNARFSIZE = 1024
verbose = None
def __init__(self, server="gopher://gopher.floodgap.com", port=70):
Connection.Connection.__init__(self)
self.server = re.sub("gopher://", "", server, 1)
self.port = port
self.forgetResponse()
return None
def forgetResponse(self):
"""Remove the response field of this object. This is periodically
necessary, since it can get quite large."""
self.response = None
return self.response
def stripTail(self, data):
ind = rfind(data, "\r\n.\r\n")
if ind != -1:
if self.verbose:
print "Stripping protocol footer at index %d" % int(ind)
return data[0:ind]
if self.verbose:
print "No protocol footer found."
return data
# Get extended information about a resource.
def getInfo(self, resource, msgBar=None):
try:
req = "%s\t!\r\n" % resource.getLocator()
data = self.requestToData(resource, req, msgBar)
except Connection.ConnectionException, errstr:
raise GopherConnectionException, errstr
if self.verbose:
print "Got %d bytes from INFO conn:\n%s" % (len(data),
data)
# The server sends back a length of -2 when it doesn't know how long
# the document is, and when the document may contain the \r\n.\r\n
# pattern. So if it might, do not strip it out. Otherwise do. This
# will probably keep out a very subtle bug of having files downloaded
# be truncated in really weird places. (Where the \r\n.\r\n would have
# been)
if resource.getLen() != -2:
if self.verbose:
print "Stripping protocol footer."
data = self.stripTail(data)
try:
info = ResourceInformation.ResourceInformation(data)
except Exception, estr:
print "*********************************************************"
print "***GopherConnection: ResourceInformation Error: %s" % estr
print "*********************************************************"
raise GopherConnectionException, estr
return info
def getResource(self, resource, msgBar=None):
self.forgetResponse()
self.host = re.sub("gopher://", "", resource.getHost(), 1)
self.port = resource.getPort()
self.lastType = resource.getType()
try:
if resource.getDataBlock():
request = resource.getLocator() + "\t+\t1\r\n"
request = request + resource.getDataBlock()
self.response = self.requestToData(resource,
request,
msgBar, 1)
elif resource.isGopherPlusResource() and resource.isAskType():
info = resource.getInfo(shouldFetch=1)
af = AskForm.AskForm(info.getBlock("ASK"))
# Copy host/port/locator information into af
af.dup(resource)
return af
elif resource.isGopherPlusResource():
request = resource.getLocator() + "\t+\r\n"
self.response = self.requestToData(resource,
request,
msgBar, 1)
else:
request = resource.getLocator() + "\r\n"
self.response = self.requestToData(resource,
request,
msgBar, None)
except Connection.ConnectionException, estr:
error_resp = GopherResponse.GopherResponse()
errstr = "Cannot fetch\n%s:\n%s" % (resource.toURL(),
estr)
error_resp.setError(errstr)
return error_resp
utils.msg(msgBar, "Examining response...")
resp = GopherResponse.GopherResponse()
resp.setType(resource.getTypeCode())
if resource.getLen() != -2:
self.response = self.stripTail(self.response)
try:
# The parser picks up directory entries and sets the internal
# data of the object as needed.
resp.parseResponse(self.response)
# if we get this far, then it's a directory entry, so set the
# data to nothing.
resp.setData(None)
except Exception, erstr:
# print "Caught exception while parsing response: \"%s\"" % erstr
if self.verbose:
print "OK, it's data."
resp.setData(self.response)
return resp
syntax highlighted by Code2HTML, v. 0.9.1