当前位置:   article > 正文

Python socket 访问网站发送 HTTP POST请求,从而深刻理解 HTTP 协议_python socket post

python socket post

用最原始的包 socket 居然可以访问网站模拟发送 POST 请求,只要发送的字符串符合 HTTP 协议,这是最大的收获。
更进一步的参考 https://www.jianshu.com/p/f196c74e72dd

import socket
input_dict = {'name':'cheng', 'age':23}

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect(('192.168.56.101', 8082))
  • 1
  • 2
  • 3
  • 4
  • 5

模拟 POST 请求
Case1:

s.send('POST /myself_login/ HTTP/1.1\r\nHost:192.168.56.101:8082\r\nContent-Type:application/x-www-form-urlencoded\r\nusername:administartor\r\npassword:start01a\r\nConnection:close\r\n\r\n')
  • 1

Case2:下面的请求中的字符串是:通过抓取 浏览器访问登录页同时输入用户名和密码时的 POST 包得来的

s.send('POST /myself_login/ HTTP/1.1\r\nHost: 192.168.56.101:8082\r\nUser-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:68.0) Gecko/20100101 Firefox/68.0\r\nAccept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\r\nAccept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2\r\nAccept-Encoding: gzip, deflate\r\nReferer: http://192.168.56.101:8082/myself_login/\r\nContent-Type: application/x-www-form-urlencoded\r\nContent-Length: 34\r\nConnection: keep-alive\r\nCookie: csrftoken=uz8SRQan48GXYbidToOP7QGyDFoMTuGEiJDQiKql0b4cRB8X86OCAMIvzHzkXUZk; sessionid=3axevcp707rdia0jbiedo1dh09zaxvxe; rob_testcookie=robert\r\nUpgrade-Insecure-Requests: 1\r\n\r\nusername=administartor&password=start01a')
  • 1

case3:后来发现其实不用那么多内容,只需要 Host/Content-Type/Content-Length 即可,没有 Content-Length 的话, Django 后端是不解析或解析不到 body 的(根据 send 里的内容可知 setting.py 中一定是注释掉了 django.middleware.csrf.CsrfViewMiddleware,如果打开该注释还想成功发送请求,则需要增加 \r\nX-CSRFToken: abcd\r\nCookie: csrftoken=abcd 由 Django csrf 原理可知 crsf 的值可以随意填写只要 X-CSRFToken 和 cookie 中的 csrftoken 一致即可

s.send('POST /myself_login/ HTTP/1.1\r\nHost: 192.168.56.101:8082\r\nContent-Type: application/x-www-form-urlencoded\r\nContent-Length: 34\r\n\r\nusername=administartor&password=start01a')
print '----------'
buffer = []

while True:
    d = s.recv(1024)
    if d:
        buffer.append(d)
    else:
        break
data = ''.join(buffer)
s.close()
header, html = data.split('\r\n\r\n', 1)
print 'Response Header is:'
print header

with open('sina.html', 'wb') as f:
	f.write(html)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18

注意当发送请求用的是 case 1 版本时: 
s.send('POST /myself_login/ HTTP/1.1\r\nHost:192.168.56.101:8082\r\nContent-Type:application/x-www-form-urlencoded\r\nusername:admin\r\npassword:start01all\r\nConnection:close\r\n\r\n')
同时服务端的写法如下即从 reqeust.META 中获取用户名和密码的:
if request.method == 'POST':
    username = request.POST.get('username')
    password = request.POST.get('password')
    print 'request.body = {0}'.format(request.body)
    print 'request.POST = {0}'.format(request.POST)
    print 'request.META = {0}'.format(request.META)
    username = request.META.get('HTTP_USERNAME')
    password = request.META.get('HTTP_PASSWORD')


root@robert-Ubuntu:~#  python raw_socket.py 
Response Header is:
HTTP/1.0 302 FOUND
Date: Tue, 30 Jul 2019 03:09:25 GMT
Server: WSGIServer/0.1 Python/2.7.12
Vary: Cookie
X-Frame-Options: SAMEORIGIN
Content-Type: text/html; charset=utf-8
Location: http://192.168.56.101:8082/hello
name: ==robert===
Set-Cookie:  sessionid=wxnc3franlzrqrx1huawdmvei9c3qhsk; expires=Tue, 13-Aug-2019 03:09:25 GMT; httponly; Max-Age=1209600; Path=/
Set-Cookie:  rob_testcookie=robert; Path=/
root@robert-Ubuntu:~# 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26

灵感来自: TCP编程

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/盐析白兔/article/detail/181202
推荐阅读
相关标签
  

闽ICP备14008679号