def drain(): global window_conn global window_stream global conn global global_stream_id global tosend_by_stream for stream_id in tosend_by_stream: tosend = tosend_by_stream[stream_id] while not tosend.empty() and window_conn and window_stream[stream_id]: max_cur_frame = min(max_frame, window_conn, window_stream[stream_id]) datablock = http2.encode_next_data(stream_id, tosend, 1, max_cur_frame) conn.sendall(http2.encode_frame(datablock)) window_conn -= len(datablock.payload) window_stream[stream_id] -= len(datablock.payload)
import socket import base64 import http11 import http2 domain = "www.google.fi" hdrs = "" hdrs += "GET / HTTP/1.1\r\n" hdrs += "Host: " + domain + "\r\n" hdrs += "Connection: Upgrade, HTTP2-Settings\r\n" hdrs += "Upgrade: h2c\r\n" settings = http2.encode_frame(http2.encode_settings([], 0)) settings = base64.urlsafe_b64encode(settings) settings = settings.replace('=', '') hdrs += "HTTP2-Settings: " + settings + "\r\n" hdrs += "\r\n" s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.connect((domain, 80)) s.send(hdrs) data = "" while True: data += s.recv(1024) if not data: break if '\r\n\r\n' in data: print data break head = data[:data.find('\r\n\r\n')]
| ssl.OP_NO_TLSv1_1) conn = context.wrap_socket(socket.socket(socket.AF_INET), server_hostname=hostname) conn.connect((hostname, port)) print(conn.selected_alpn_protocol()) conn.sendall( b'\x50\x52\x49\x20\x2a\x20\x48\x54\x54\x50\x2f\x32\x2e\x30\x0d\x0a\x0d\x0a\x53\x4d\x0d\x0a\x0d\x0a' ) # MAGIC settings = http2.encode_frame( http2.encode_settings( [ http2.setting_header_table_size(8192), http2.setting_enable_push(1), http2.setting_max_concurrent_streams(10), http2.setting_initial_window_size(65535), #http2.setting_initial_window_size(1), http2.setting_max_frame_size(16384), http2.setting_max_header_list_size(65536), ], 0)) conn.sendall(settings) #conn.sendall(b'\x50\x52\x49\x20\x2a\x20\x48\x54\x54\x50\x2f\x32\x2e\x30\x0d\x0a\x0d\x0a\x53\x4d\x0d\x0a\x0d\x0a' + settings) # MAGIC b = http2.recv_frame(conn) settings_srv = http2.decode_any(b) if type(settings_srv) != http2.frame_settings: assert False hdrsz = 4096 max_frame = 16384
from scapy.all import * import http2 import hpack pkts=[] seq=1 def send(x): global seq pkts.append(Ether() / IP() / TCP(flags='A',seq=seq,sport=12345,dport=80) / x) seq += len(x) send(b'\x50\x52\x49\x20\x2a\x20\x48\x54\x54\x50\x2f\x32\x2e\x30\x0d\x0a\x0d\x0a\x53\x4d\x0d\x0a\x0d\x0a') settings = http2.encode_frame(http2.encode_settings([], 0)) send(settings) hdrs = hpack.encodehdrs([ (':method', 'GET'), (':scheme', 'https'), (':path', '/'), ('host', 'www.google.fi'), ('accept', 'text/html'), ], hpack.hdrtbl()) end_stream = 1 send(http2.encode_frame(http2.encode_headers(1, 0, 0, 0, hdrs, end_stream, 0, 16384)[0])) wrpcap('http2.pcap', pkts)
# conn = context.wrap_socket(tcp_conn, server_side=True) print(conn.selected_alpn_protocol()) try: data = http2.recvall( conn, len(b'\x50\x52\x49\x20\x2a\x20\x48\x54\x54\x50\x2f\x32\x2e\x30\x0d\x0a\x0d\x0a\x53\x4d\x0d\x0a\x0d\x0a' )) if data != b'\x50\x52\x49\x20\x2a\x20\x48\x54\x54\x50\x2f\x32\x2e\x30\x0d\x0a\x0d\x0a\x53\x4d\x0d\x0a\x0d\x0a': assert False except ssl.SSLError: continue settings = http2.encode_frame( http2.encode_settings([ http2.setting_header_table_size(8192), ], 0)) conn.sendall(settings) hdrtbl = hpack.hdrtbl() enctbl = hpack.hdrtbl() hdrsz = 4096 print "LOOP" while True: b = http2.recv_frame(conn) if len(b) == 0: break a = http2.decode_any(b) if type(a) == http2.frame_push_promise: