1 from twisted.internet.protocol import ClientFactory
2 from twisted.web2.client.http import HTTPClientProtocol
3 from twisted.internet import reactor, error
4 from urlparse import urlsplit
5 from socket import gethostbyname
6 from urllib import urlencode as urllib_urlencode, quote_plus as urllib_quote_plus
8 global HTTPCLIENT_requestCount
9 HTTPCLIENT_requestCount = 0 # counts requests
11 class Enigma2HTTPRequest:
13 def __init__(self,hostname,path,port,method="GET",headerfields={}):
14 self.hostname=hostname
18 self.headerfields = headerfields
19 self.onRequestFinished = []
20 self.onRequestError = []
21 self.onHeaderLoaded = []
27 def _DataRecived(self,data):
28 self.readsize += len(data)
31 def getIPAdress(self):
33 socket.gethostbyname() is syncron
34 Enigma2 is blocked while process is running
37 return gethostbyname(self.hostname)
41 def HeaderLoaded(self,headers):
42 self.headers = headers
43 for i in self.onHeaderLoaded:
46 self.onHeaderLoaded=[]
48 def RequestError(self,error):
49 for i in self.onRequestError:
52 self.onRequestError = []
54 def RequestFinished(self,data):
55 for i in self.onRequestFinished:
59 class Enigma2URLHTTPRequest(Enigma2HTTPRequest):
60 def __init__(self,url,method="GET",headerfields={}):
70 Enigma2HTTPRequest.__init__(self,hostname,path,port,method=method,headerfields=headerfields)
72 class Enigma2FileHTTPRequest(Enigma2URLHTTPRequest):
73 def __init__(self,targetfile,url,method="GET",headerfields={}):
74 Enigma2URLHTTPRequest.__init__(self,url,method=method,headerfields=headerfields)
75 self.filehandle = open(targetfile,"w")
76 self.onRequestFinished.append(self.close)
77 self.onRequestError.append(self.close)
78 def close(self,dummy):
79 self.filehandle.close()
81 def _DataRecived(self,data):
82 self.readsize += len(data)
83 self.filehandle.write(data)
88 class Enigma2HTTPProtocol(HTTPClientProtocol):
91 def __init__(self,request,requestCount):
92 self.request = request
93 self.requestCount = requestCount
96 self.responseFirstLine = True # to indikate, that first line of responseheader was read
97 HTTPClientProtocol.__init__(self)
100 def rawDataReceived(self,line):
101 for l in line.split(self.delimiter):
103 self.request._DataRecived(l)
106 print "HTTP "+self.requestCount+" <<==",l
108 self.headerread = True
109 self.request.HeaderLoaded(self.headers)
111 self.parseHeaderLine(l)
113 def parseHeaderLine(self,line):
114 if self.responseFirstLine is True:
115 #print "parseHeaderLine",line.split(" ")
116 fields = line.split(" ")
117 protocoll = fields[0]
118 responsecode = fields[1]
119 statuscode = " ".join(fields[2:])
120 self.headers["protocoll"] = protocoll
121 self.headers["responsecode"] = responsecode
122 self.headers["statuscode"] = statuscode
123 self.responseFirstLine = False
124 elif line.rfind(":"):
126 key = x[0].lstrip().rstrip().lower()
127 var = ":".join(x[1:]).lstrip()
128 self.headers[key] = var
130 print "unknown headerline",line
132 def connectionMade(self):
133 if self.request.method == "POST":
134 (path,params ) = self.request.path.split("?")
135 elif self.request.method == "GET":
136 path = self.request.path
137 self.sendLine("%s %s HTTP/1.0"%(self.request.method,path))
138 self.sendLine("Host: %s"%self.request.hostname)
139 for i in self.request.headerfields:
140 self.sendLine(i+": "+self.request.headerfields[i])
141 if self.request.method == "POST":
142 self.sendLine("Content-Type: application/x-www-form-urlencoded")
143 self.sendLine("Content-Length: "+str(len(params)))
146 if self.request.method == "POST":
147 self.sendLine(params)
149 def sendLine(self,data):
151 print "HTTP "+self.requestCount+" ==>>",data
152 HTTPClientProtocol.sendLine(self,data)
154 class Enigma2HTTPClientFactory(ClientFactory):
158 def __init__(self,request):
159 self.hangup_ok = False
160 self.request = request
162 def startedConnecting(self, connector):
165 def buildProtocol(self, addr):
166 global HTTPCLIENT_requestCount
167 HTTPCLIENT_requestCount = HTTPCLIENT_requestCount + 1
168 return Enigma2HTTPProtocol(self.request,str(HTTPCLIENT_requestCount))
170 def clientConnectionLost(self, connector, reason):
171 if not self.hangup_ok:
172 self.request.RequestFinished(self.request.data)
173 ClientFactory.clientConnectionLost(self, connector, reason)
175 def clientConnectionFailed(self, connector, reason):
176 self.request.RequestError(reason.getErrorMessage())
177 ClientFactory.clientConnectionFailed(self, connector, reason)
180 return urllib_urlencode(dict)
182 def quote_plus(data):
183 return urllib_quote_plus(data)
185 def getURL(url,callback=None,errorback=None,headercallback=None,method="GET",headers={}):
187 this will is called with a url
188 url = http://www.hostna.me/somewhere/on/the/server <string>
190 req = Enigma2URLHTTPRequest(url,method=method,headerfields=headers)
191 req.onRequestError.append(errorback)
192 req.onHeaderLoaded.append(headercallback)
193 req.onRequestFinished.append(callback)
194 ipadress = req.getIPAdress()
195 if ipadress is not False:
196 reactor.connectTCP(ipadress,req.port, Enigma2HTTPClientFactory(req))
199 if errorback is not None:
200 errorback("Error while resolve Hostname")
202 def getPage(hostname,port,path,method="GET",callback=None,errorback=None,headercallback=None,headers={}):
204 this will is called with separte hostname,port,path
205 hostname = www.hostna.me <string>
207 path= /somewhere/on/the/server <string>
209 req = Enigma2HTTPRequest(hostname,path,port,method=method,headerfields=headers)
210 req.onRequestError.append(errorback)
211 req.onRequestFinished.append(callback)
212 ipadress = req.getIPAdress()
213 if ipadress is not False:
214 reactor.connectTCP(ipadress,req.port, Enigma2HTTPClientFactory(req))
217 if errorback is not None:
218 errorback("Error while resolve Hostname")
220 def getFile(filename,url,method="GET",callback=None,errorback=None,headercallback=None,headers={}):
222 this will is called with a url and a target file
223 fimename = /tmp/target.jpg
224 url = http://www.hostna.me/somewhere/on/the/server.jpg <string>
226 req = Enigma2FileHTTPRequest(filename,url,method=method,headerfields=headers)
227 req.onRequestError.append(errorback)
228 req.onHeaderLoaded.append(headercallback)
229 req.onRequestFinished.append(callback)
230 ipadress = req.getIPAdress()
231 if ipadress is not False:
232 reactor.connectTCP(ipadress,req.port, Enigma2HTTPClientFactory(req))
235 if errorback is not None:
236 errorback("Error while resolve Hostname")