def check_appid_exists(appid): request_params = gae_params_dict[appid] if isinstance(request_params, gae_params): http_util = http_gws else: if not hasattr(request_params, 'hostname'): _, (iporname, _) = get_connect_action(request_params.ssl, request_params.host) request_params.hostname = set_dns(request_params.host, iporname) http_util = http_nor connection_cache_key = '%s:%d' % (request_params.hostname, request_params.port) for _ in range(3): err = None response = None try: sock = http_util.create_ssl_connection( (request_params.host, request_params.port), request_params.hostname, connection_cache_key) sock.sendall(b'HEAD / HTTP/1.1\r\n' b'Host: %s\r\n' b'Connection: Close\r\n\r\n' % host.encode()) response = HTTPResponse(sock, method='HEAD') response.begin() except: err = True finally: if response: response.close() if err is None: exists = response.status in (200, 503) if exists: http_util.ssl_connection_cache[ connection_cache_key].append((time(), sock)) return exists
def __init__(self, request, proxy_socket): HttpTransfer.__init__(self) self.request = request h = HTTPResponse(proxy_socket) h.begin() # HTTPResponse会将所有chunk拼接到一起,因此会直接得到所有内容,所以不能有Transfer-Encoding del h.msg['Transfer-Encoding'] del h.msg['Content-Length'] self.response_version = self.version_dict[h.version] self.status = h.status self.reason = h.reason self.set_headers(h.msg) self.decoding = None self.language = self.system = self.webserver = None try: data = h.read() body_data = self._decode_content_body( data, self.get_header('Content-Encoding')) except http.client.IncompleteRead: body_data = b'' except zlib.error: body_data = b'' except _socket.timeout: body_data = b'' self.set_body_data(body_data) self._text() # 尝试将文本进行解码 h.close() proxy_socket.close()
def check_appid_exists(appid): request_params, http_util, connection_cache_key = _get_request_params( appid) for _ in range(3): err = None response = None try: sock = http_util.create_ssl_connection( (request_params.host, request_params.port), request_params.hostname, connection_cache_key) sock.sendall(b'HEAD / HTTP/1.1\r\n' b'Host: %s\r\n' b'Connection: Close\r\n\r\n' % host.encode()) response = HTTPResponse(sock, method='HEAD') response.begin() except: err = True finally: if response: response.close() if err is None: exists = response.status in (200, 503) if exists: http_util.ssl_connection_cache[ connection_cache_key].append((time(), sock)) return exists
def do_COMMAND(self): log.info(f"{self.command} {self.path}") try: # Connect to destination self._connect_to_host() except Exception as e: self.send_error(500, str(e)) return # The request that got sent to the website: self # Browser <--> [Proxy <--> Website] content_length = int(self.headers.get("Content-Length", 0)) request_body = self.rfile.read(content_length) # Build request which will be sent to the client # [Browser <--> Proxy] <--> Website client_request = ( # Add "GET / HTTP/1.1..." to the request" b" ".join([ to_bytes(self.command), to_bytes(self.path), to_bytes(self.request_version), ]) + CRLF # Add Headers to the request (Host:..., User-Agent:...) + self.headers.as_bytes() + CRLF + request_body) # Send it down the pipe! self.server.send(to_bytes(client_request)) # Parse response h = HTTPResponse(self.server.conn) h.begin() # Get rid of hop-by-hop headers orig_response = h self.filter_headers(h.msg) # Time to relay the message across # read response body response_body = h.read() res = ( # HTTP/1.1 OK b" ".join([ to_bytes(self.request_version), to_bytes(h.status), to_bytes(h.reason), ]) # Content-Type, Content-Length, Server... + CRLF + h.msg.as_bytes() + CRLF + response_body) # Let's close off the remote end h.close() self.server.close() # Relay the message self.client.send(res) self.print_info(self, request_body, orig_response, response_body)
def read_response(self, sock): response = HTTPResponse(sock) response.begin() content = response.read() status_code = response.status reason = response.reason headers = dict(response.getheaders()) response.close() return FakeResponse(status_code, reason, headers, content)
def close(self): # Consume any remaining data in the socket try: while select((self.fp._sock,), (), (), 0)[0]: if not self.fp._sock.recv(256): break except AttributeError: pass HTTPResponse.close(self) try: self._handler.free_connection(self._connection) except AttributeError: pass
def close(self): # Consume any remaining data in the socket try: while select((self.fp._sock, ), (), (), 0)[0]: if not self.fp._sock.recv(256): break except AttributeError: pass HTTPResponse.close(self) try: self._handler.free_connection(self._connection) except AttributeError: pass
def do_COMMAND(self): # Is this an SSL tunnel? if not self.is_connect: try: # Connect to destination self._connect_to_host() except Exception as e: self.send_error(500, str(e)) return # Extract path # Build request req = '%s %s %s\r\n' % (self.command, self.path, self.request_version) # Add headers to the request req += '%s\r\n' % self.headers # Append message body if present to the request if 'Content-Length' in self.headers: req += self.rfile.read(int(self.headers['Content-Length'])) # Send it down the pipe! self._proxy_sock.sendall(self.mitm_request(req)) # Parse response h = HTTPResponse(self._proxy_sock) h.begin() # Get rid of the pesky header del h.msg['Transfer-Encoding'] # Time to relay the message across res = '%s %s %s\r\n' % (self.request_version, h.status, h.reason) res += '%s\r\n' % h.msg res += h.read() # Let's close off the remote end h.close() self._proxy_sock.close() # Relay the message self.request.sendall(self.mitm_response(res))
def check_appid_exists(appid): host = '%s.appspot.com' % appid for _ in range(3): err = None response = None try: sock = http_gws.create_ssl_connection((host, 443), 'google_gae', 'google_gae|:443') sock.sendall(b'HEAD / HTTP/1.1\r\n' b'Host: %s\r\n' b'Connection: Close\r\n\r\n' % host.encode()) response = HTTPResponse(sock, method='HEAD') response.begin() except: err = True finally: if response: response.close() if err is None: exists = response.status in (200, 503) if exists: http_gws.ssl_connection_cache['google_gae|:443'].append((time(), sock)) return exists
def __init__(self, request,proxy_socket): HttpTransfer.__init__(self) self.request = request h = HTTPResponse(proxy_socket) h.begin() ##HTTPResponse会将所有chunk拼接到一起,因此会直接得到所有内容,所以不能有Transfer-Encoding del h.msg['Transfer-Encoding'] del h.msg['Content-Length'] self.response_version =self.version_dict[h.version] self.status = h.status self.reason = h.reason self.set_headers(h.msg) body_data = self._decode_content_body(h.read(),self.get_header('Content-Encoding')) self.set_body_data(body_data) self._text()#尝试将文本进行解码 h.close() proxy_socket.close()
def __init__(self, request, proxy_socket): HttpTransfer.__init__(self) self.request = request h = HTTPResponse(proxy_socket) h.begin() ##HTTPResponse会将所有chunk拼接到一起,因此会直接得到所有内容,所以不能有Transfer-Encoding del h.msg['Transfer-Encoding'] del h.msg['Content-Length'] self.response_version =self.version_dict[h.version] self.status = h.status self.reason = h.reason self.set_headers(h.msg) body_data = self._decode_content_body(h.read(), self.get_header('Content-Encoding')) self.set_body_data(body_data) self._text()#尝试将文本进行解码 h.close() proxy_socket.close()
class HTTPResponseWrapper(object): """ Class that adds some additional utilities to the build in HTTPResponse class. """ def __init__(self, oSock, sHttpVer): """ :param oSock: Communication socket. :param sHttpVer: Version of the http protocol we are using. """ self.oHTTPResponse = HTTPResponse(oSock) self.oHTTPResponse.begin() self.bBody = self.oHTTPResponse.read() self.bResponseLine = '{0} {1} {2}\r\n'.format( sHttpVer, self.oHTTPResponse.status, self.oHTTPResponse.reason).encode() self.bHeaders = self.oHTTPResponse.msg.as_bytes() self.sEncoding = self.oHTTPResponse.getheader('Content-Encoding') self.sContentType = self.oHTTPResponse.getheader('Content-Type') self.oHTTPResponse.close() def __bytes__(self): """ :return: Raw bytes of the http response. """ return self.bResponseLine + self.bHeaders + self.bBody def getDecodedBody(self): """ :return: Decoded content body of the http response. """ # Only gzip encoding and html content types are supported at the moment. if self.sEncoding == CONTENT_ENCODINGS.GZIP and CONTENT_TYPES.HTML in self.sContentType: try: # Zlib lets us decompress the gzipped contents as stored bytes. return zlib.decompress(self.bBody, 16 + zlib.MAX_WBITS) except Exception as e: print("Error decompressing gzip contents {0}".format(str(e)))
def do_POST(self): try: # Connect to destination self._connect_to_host() except Exception as e: self.send_error(500, str(e)) return # The request that contains the request to the website is located # inside the POST request body from the stegoclient log.debug("Got stego-request from stegoclient") # io stream that represents the stego medium (i.e. image) req_body = io.BytesIO( self.rfile.read(int(self.headers.get("Content-Length", 0)))) stego_message = stego.extract(medium=req_body) # Get Host and Port from the original request host, port = self._get_hostaddr_from_headers(stego_message) # establish connection to the website log.info(f"Connecting to {host}:{port}") self.server = Server(host=host, port=port) # Just relay the original request to the website log.debug("Relaying extracted request to website") self.server.send(stego_message) # Parse response from website h = HTTPResponse(self.server.conn) h.begin() # Get rid of hop-by-hop headers self.filter_headers(h.msg) # Build response from website log.debug("Building response from website") stego_resp = self._build_stego_response(self.request_version, h.status, h.reason, h.msg, h.read()) # Build header to stegoclient header = Message() header.add_header("Host", f"{cfg.REMOTE_ADDR[0]}:{cfg.REMOTE_ADDR[1]}") header.add_header("Connection", "keep-alive") cover = self._get_cover_object() max_size = self._calc_max_size(cover) resp_len = len(stego_resp) if (max_size is not None and resp_len > max_size): log.debug( f"Can't fit response ({resp_len} bytes) into stego-response - " f"splitting into chunks of {max_size} bytes.") header.add_header("Transfer-Encoding", "chunked") resp_to_client = self._build_response_header( cfg.STEGO_HTTP_VERSION, h.status, h.reason, header) # Send headers to client log.debug("Sending chunked stego-response header to stegoclient") self.client.send(resp_to_client) start = time.time() chunk_count = 0 for chunk in self._split_into_chunks(stego_resp, max_size): if isinstance(cover, Image.Image): tmp_cover = cover.copy() else: tmp_cover = cover # Send chunks log.debug(f"Sending chunk with size: {len(chunk)} bytes") self._write_chunks(stego.embed(cover=tmp_cover, message=chunk)) chunk_count += 1 end = time.time() # send "end of chunks" trailer self._write_end_of_chunks() log.debug(f"{chunk_count} chunks sent in {end - start:.2f}s.") else: # Encapsulate response inside response to stego client log.debug("Embedding response from website in stego-response") start = time.time() stego_medium = stego.embed(cover=cover, message=stego_resp) end = time.time() log.debug( f"Took {end - start:.2f}s to embed response in stego-response") header.add_header("Content-Length", str(len(stego_medium))) resp_to_client = self._build_response(cfg.STEGO_HTTP_VERSION, h.status, h.reason, header, stego_medium) # Relay the message log.debug("Relaying stego-response to stegoclient") self.client.send(resp_to_client) if isinstance(cover, Image.Image): cover.close() # Let's close off the remote end h.close() self.server.close()
def _relay_response(self, debuglevel=0): resp = HTTPResponse(self.shadowsocks, method=self.command) resp.begin() # attempt to reuse the shadow socket self.close_connection = resp.will_close if self.close_connection: self.shadowsocks.close() self.shadowsocks = None if self.debuglevel > 0: # pass print("[_relay_response] [%s] resp.will_close=%s" % (self.requestline, resp.will_close)) ver_str = self.protocol_version if resp.version == 10: ver_str = "HTTP/1.0" reply = "%s %s %s\r\n" % (ver_str, resp.code, resp.reason) if resp.headers: for hdr in resp.headers: val = resp.headers[hdr] reply += "%s: %s\r\n" % (hdr, val) reply += "%s: %s\r\n" % ("Z-Relayed-By", "Python Proxy Server 0.0.2") reply += "\r\n" reply = reply.encode("latin-1", "strict") # if debuglevel > 0: print("response header:", header) # self.request.send(header) # self.close_connection = True # Message body is omitted for cases described in: # - RFC7230: 3.3. 1xx, 204(No Content), 304(Not Modified) # - RFC7231: 6.3.6. 205(Reset Content) if (self.command == 'HEAD' or resp.code < HTTPStatus.OK or resp.code in (HTTPStatus.NO_CONTENT, HTTPStatus.RESET_CONTENT, HTTPStatus.NOT_MODIFIED)): if resp.will_close: resp.close() if debuglevel > 0: print("reply:", reply) self.request.send(reply) return resp.code, reply resp_body = resp.read() if resp.chunked: resp_size = len(resp_body) reply += ("%x\r\n" % resp_size).encode("utf-8") reply += resp_body + b'\r\n' reply += b'0\r\n' elif len(resp_body) > 0: reply += resp_body reply += b'\r\n' self.request.send(reply) if debuglevel > 0: print("reply:", reply) if self.debuglevel > 0: print("[_relay_response]", resp.code, resp.reason, self.requestline) if resp.will_close: resp.close() if resp.code == HTTPStatus.UNAUTHORIZED: self._blind_relay() return resp.code, reply