基于django做HTTP代理服务器

这个项目实现了:

a) 网站过滤:允许/不允许访问某些网站;

b) 用户过滤:支持/不支持某些用户访问外部网站;

c) 网站引导:将用户对某个网站的访问引导至一个模拟网站(钓
鱼)。

d) 缓存功能:要求能缓存原服务器响应的对象,并能够通过修改请求报文(添加 if-modified-since头行),向原服务器确认缓存对象是否是最新版本

首先,先要把django包内的C:\Python27\Lib\site-packages\django\core\handlers\base.py 中的^$改为.* 。(共有两处需要修改),以此来保证能让所有的url目标都传到views里面的函数中。
如图
image1

然后构建一个django项目,可以不带有admin模块,然后建立一个新的app
博主构建的项目结构如下,其中Cache.py是一会再创建的
image2

下面是models.py的代码

#coding=utf8
from django.db import models


class fish(models.Model):
    #钓鱼规则表
    user_ip = models.CharField(max_length=15) #客户ip
    forbidden_host = models.CharField(max_length=100)  #禁止的host
    fish_url = models.CharField(max_length=100)  #跳转的网站链接


class firewall(models.Model):
    #黑名单规则表
    user_ip = models.CharField(max_length=15)   #客户ip
    forbidden_host = models.CharField(max_length=100)  #禁止的host


class cache(models.Model):
    #缓存表
    timestamp = models.CharField(max_length=80) #时间戳
    name = models.CharField(max_length=150) #文件名对应的url
    content_type = models.CharField(max_length=50)  #内容类型
    content = models.TextField()  #内容


def check_if_replace(user_ip, host):
    user_list = firewall.objects.filter(user_ip=user_ip).all()  #先到黑名单中查找
    for user in user_list:
        if user.forbidden_host in host or host == '*':
            return (1, '<h1>You have been forbidden!</h1>') #返回禁止页
    general = firewall.objects.filter(user_ip='*').all()
    for i in general:
        if i.forbidden_host in host:
            return (1, '<h1>You have been forbidden!</h1>')
    fish_list = fish.objects.filter(user_ip=user_ip).all()  #然后到钓鱼规则中查找
    for fisher in fish_list:
        if fisher.forbidden_host in host:
            return (-1, fisher.fish_url)
    return (0, host)

这一部分是用来做规则的存储和缓存的存储,migrate之后各表如下所示
image3
这张表用来做禁止规则的配置,可以用'*'作为通配符,实现所有用户对单一网站和对某用户做屏蔽。

image4
这张表用来做钓鱼规则的配置,用户转到指定的目标

image5
这张表作为缓存的实现

views.py的代码:

#coding=utf8
import re
from contextlib import closing
from django.http import HttpResponse,HttpResponseRedirect
from Cache import *
def home(request):
    url = request.path[1:].split('/')
    url = url[0] + '//' + url[1] + '/'
    url = request.path[1:].replace(':/', '://')  #获得目标url
    host = request.get_host()
    method = request.method
    if request.META.has_key('HTTP_X_FORWARDED_FOR'):
        ip = request.META['HTTP_X_FORWARDED_FOR']  #获取客户端ip
    else:
        ip = request.META['REMOTE_ADDR']
    regex = re.compile('^HTTP_')
    headers = dict((regex.sub('', header), value) for (header, value)
                   in request.META.items() if header.startswith('HTTP_'))
    if len(request.REQUEST.items()) > 0:
        url += '?'
        for (i, j) in request.REQUEST.items():
            url += str(i) + '=' + str(j) + '&'
        url = url[:-1]  #将带参数的get请求恢复成原始链接状态
    check_tuple = check_if_replace(ip, host)
    if check_tuple[0] == 1:
        return HttpResponse(check_tuple[1])  #如果符合黑名单规则,返回禁止页
    elif check_tuple[0] == -1:
        url = check_tuple[1]
        return HttpResponseRedirect(url)   #如果符合钓鱼规则,那么重定向到指定的网站
    cacher = Cache(url)
    if cacher.check_cache():      #检查是否有与目标网站一致的资源
        res = cacher.get()
        return HttpResponse(res[0], content_type=res[1])  #将缓存的内容返回
    else:
        with closing(requests.request(method, url, headers=headers, data=request.POST, stream=True)) as r:
            cacher.update(bytes(r.content), content_type=r.headers['content-type'])  #更新缓存
            return HttpResponse(bytes(r.content), status=r.status_code, content_type=r.headers['content-type'])  #返回资源

Cache.py的代码

#coding=utf8
import requests
from models import *
import time
class Cache():
    def __init__(self, url):
        self.url = url

    def check_cache(self):
        '''
        检查是否有一致的缓存
        :return: Boolean型
        '''
        try:
            f = cache.objects.get(name=self.url)
            headers = {'If-Modified-Since': f.timestamp}
            if requests.get(self.url, headers=headers).status_code == 304:
                return True
            else:
                return False
        except:
            return False

    def update(self, content, content_type):
        '''
        更新缓存
        :param content: 内容
        :param content_type: 内容类型
        :return:
        '''
        try:
            f = cache.objects.get(name=self.url)
            f.content = content
            f.content_type = content_type
            f.name = self.url
            t = time.asctime().split()
            f.timestamp = t[0] + ', '+t[2] + ' '+t[1] +' '+t[4]+' '+t[3] + 'GMT'
            f.save()
        except:
            f = cache()
            f.content = content
            f.name = self.url
            t = time.asctime().split()
            f.timestamp = t[0] + ', ' + t[2] + ' ' + t[1] + ' ' + t[4] + ' ' + t[3] + ' GMT'
            f.content_type = content_type
            f.save()

    def get(self):
        #获取缓存
        f = cache.objects.get(name=self.url)
        return (f.content, f.content_type)

最后修改urls.py

from django.conf.urls import include, url
# from django.contrib import admin
from server.views import *
urlpatterns = [
    # url(r'^admin/', include(admin.site.urls)),
    url('.*',home),
]

为了防止post的时候受干扰,把settings.py中的中间件去掉csrf,剩下的如图
image6

下面启动项目,监听8000端口
image7

把浏览器设置代理为127.0.0.1:8000
image8

打开博客园首页,正常显示
image9

访问人人网,由于黑名单的表中有这条规则,返回我们写的禁止页
image10

访问爱奇艺,由于钓鱼规则中配置了将爱奇艺引导到博客园,返回的是对博客园的重定向
image11

到此就完成了一个简单的HTTP代理服务器

转载于:https://www.cnblogs.com/chuxiuhong/p/6817858.html

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
服务器部署Vue和Django项目涉及以下步骤: 1. 首先,你需要在服务器上安装Docker,并下载并安装Nginx作为反向代理服务器。Nginx将用于处理用户请求并将其转发到正确的服务器上。 2. 然后,你需要将Vue客户端和Django服务器分别部署在不同的服务器上。Vue客户端将托管静态页面,而Django服务器将提供服务。这样可以分担高并发压力。 3. 在Vue客户端服务器上,你需要下载并安装Nginx镜像,并配置Nginx以使其能够正确地转发请求到Django服务器。这将解决客户端发送的请求应该访问哪个服务器的问题。 4. 在Django服务器上,你需要安装MySQL和Redis镜像,并配置它们以满足你的项目需求。此外,你还需要配置uwsgi服务器来执行Django项目。 5. 最后,你需要确保静态文件可以被访问。你可以通过从服务端项目中收集静态文件,并在Nginx配置中添加静态文件的访问支持来实现这一点。 总结起来,服务器部署Vue和Django项目需要安装Docker、Nginx、MySQL、Redis和uwsgi等组件,并配置它们以满足项目的需求。此外,还需要合理地分配服务器架构,使用Nginx作为反向代理服务器来转发请求,并保证静态文件的访问支持。这样可以提高系统的性能和稳定性。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *3* [vue+django项目部署](https://blog.csdn.net/weixin_42065178/article/details/124418986)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *2* [博客系统源码,基于Django v2.0.7 + Python3.6 + VUE2.0](https://download.csdn.net/download/weixin_47367099/85342192)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值