当部署线上项目的时候可能会把git代码仓库一起部署上去,造成的结果就是.git文件夹泄漏,由此可以根据.git/index来知道对应的压缩文件名字,下载之后解压缩即可得到源代码。这个程序是根据lijiejie的githack更改过来的。

因为githack使用的是socket直接read()之后解压缩,如果文件太大会造成卡死。不管是githack还是rip-git,在下载文件的时候,如果文件不存在,而且服务器设置了302跳转的话,就会下载跳转那个页面,最后会导致下载好多重复文件。

所以我在源代码的基础上更改了下,先下载git压缩文件,然后再解压缩到对应的名称,如果文件不存在,服务器跳转,就pass。中间碰到几个问题如下:

使用requests碰到的问题

timeout()

简单来说,Timeouts可以是一个元组,第一个数值代表的是connecttimeout,第二个数值表示readtimeout,在这里readtimeout表示的是is the number of seconds the client will wait for the server to send a response,(Specifically, it’s the number of seconds that the client will wait between bytes sent from the server. In practice, this is the time before the server sends the first byte)

下载大文件

使用requests,所以下载的时候不需要担心steam=True的情况,直接使用。

r = requests.get(url, stream=True)
with open(local_filename, 'wb') as f:    
    for chunk in r.iter_conteCnt(chunk_size=1024):
        if chunk:               # filter out keep-alive new chunks
            f.write(chunk)
            #f.flush() commented by recommendation from J.F.Sebastian
    return local_filename

zlib解压缩

在原有代码的基础上,使用zlib.decompress(requests.reponse.raw.read())来解压缩文件,本身设想把socket当作file来操作,但是未搞定。
最后采用先下载压缩文件到本地,然后解压缩到对应文件。

Socket流程

由于gitback在两个地方碰到了socket的问题:

  • 请求服务器发生readtimeout异常
  • zlib.decopress解压缩是否可以解压缩socket,将socket作为文件来读

首先来看以下socket的流程:首先服务端调用socket()创建一个socket,再将这个socket绑定bind(),绑定一个端口,调用listen来限制等待连接的队列容量,最后在循环中不停调用accept()来接收请求。

客户端通过socket()创建socket,再调用connect()连接到服务端bind的端口,这个时候如果等待连接的客户端超过listen()的设置,就会被拒绝,否则服务器接收这个accept()请求,并建立连接。accet()会返回新的socket,服务端和客户端都可以通过这个socket,调用send()/recv()write()/read()进行通信。

来源:http://www.keakon.net/2011/09/28/%E5%85%B3%E4%BA%8Esocket%E7%9A%84%E4%B8%80%E4%BA%9B%E5%88%9D%E6%AD%A5%E7%A0%94%E7%A9%B6

阻塞与非阻塞

阻塞(blocking),简单来说就是**sleep(休眠)**的技术术语,由于CPU的速度比较快,寄存器、CPU缓存和内存还能跟上这个速度,但是换成硬盘、网络等访问时间在毫秒以上,造成CPU长时间空闲等待,于是造成阻塞。
如果在这些耗费时间较长的I/O访问时,CPU处理完之后立即返回处理其他事情,让设备自行连接、传输。并在结束后让CPU完成善后,这样就是非阻塞(non-blocking),在C语言中可以通过fcntl()ioctl()将socket设为非阻塞。

在非阻塞状态下,服务器可以异步处理I/O,最简单的就是死循环中遍历所有socket,此时如果试着读取non-blocking的socket,如果socket没有内容的时候,返回-1,并将errno设置为EWOULDBLOCK

select()授予你同时监视多个socket的权利,它会告诉你哪里资料可以读取,那些可以写入,哪些触发了例外。

#include    <sys/time.h> 
#include    <sys/types.h> 
#include    <unistd.h> 

int select (int numfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout); 

readfdswritefds, excepfds分别表示要监视的那一组file descriptor set。

至于epoll,异步IO这些以后再慢慢学,先留个概念。

来源:https://translate.googleusercontent.com/translate_c?depth=1&hl=zh-CN&prev=search&rurl=translate.google.com.sg&sl=zh-TW&u=http://beej-zhtw.netdpi.net/07-advanced-technology/7-2-select&usg=ALkJrhg0zwDET71E2ri1ObOL_Xb3et8b8w

⬆︎TOP