TCP stream though proxy (chaining) functions

Miscellaneous Forums/Blitz Showcase/TCP stream though proxy (chaining) functions

Open TCP streams through proxy servers. Chaining supported.

It's recommended to ping proxies so it can connect to fastest one(s)

OpenProxyConnection(server$[, port%][, depth%])
Default port% is 80 and depth% is 1
depth% is the count of proxies in chain to use to reach the destination server

After successfull connection use Blitz's own TCP stream functions.

Example:
Include "multiprox.bb"

; Insert some proxies to system
AddProxy("69.88.144.162")
AddProxy("66.98.238.8", 3128)
AddProxy("65.83.25.189")
AddProxy("69.88.144.163")

; Ping proxies (first, parameter is for bandwidth testing, default is True, second is for sorting by ping (default True))
PingProxies(False, True)

; Open proxy connection
stream% = OpenProxyConnection("www.google.com", 80, 2)

WriteLine stream%, "GET / HTTP/1.1"
WriteLine stream%, "Host: www.google.com"
WriteLine stream%, "User-Agent: MultiProx"
WriteLine stream%, "Connection: Close"
WriteLine stream%, ""

Repeat
	If ReadAvail(stream%) then Print ReadLine$(stream%)
Forever
WaitKey


Functions (multiprox.bb):
; List of proxies: <a href="http://tools.rosinstrument.com/proxy/" target="_blank">http://tools.rosinstrument.com/proxy/</a>

Type proxy
	Field host$, port%
	Field ping%, bandwidth%
End Type

Function OpenProxyConnection(server$, port% = 80, depth% = 1)
	; Connect to proxies
	this.proxy = First proxy
	DebugLog "Connecting to proxy " + this\host$ + ":" + this\port% + " (" + this\ping% + "ms)..."
	stream% = OpenTCPStream(this\host$, this\port%)
	If stream%
		For d% = depth% To 1 Step -1
			If d% > 1
				this = After this
					DebugLog "Chaining proxy #" + (depth% - d% + 1) + " " + this\host$ + ":" + this\port% + " (" + this\ping% + "ms)"
					WriteLine stream%, "CONNECT " + this\host$ + ":" + this\port% + " HTTP/1.1"
					WriteLine stream%, "User-Agent: MultiProx"
					WriteLine stream%, ""
			Else
				DebugLog "Chaining destination server #" + (depth% - d% + 1) + " " + server$ + ":" + port% + "..."
				WriteLine stream%, "CONNECT " + server$ + ":" + port% + " HTTP/1.1"
				WriteLine stream%, "User-Agent: MultiProx"
				WriteLine stream%, ""
			EndIf
			
			; Waiting header
			tim% = MilliSecs()
			Repeat
				If (MilliSecs() - tim%) > 5000 Then Exit
			Until ReadAvail(stream%)
			
			; Check for headers
			While ReadAvail(stream%)
				txt$ = ReadLine$(stream%)
				If Left$(txt$, 8) = "HTTP/1.0" Or Left$(txt$, 8)= "HTTP/1.1"
					If Instr(txt$, "200")
						; Connection established
						DebugLog "Proxy #" + (depth% - d% + 1) + " - Connection established!"
						header_count% = header_count% + 1
						Exit
					Else
						; Connection failed
						DebugLog "Proxy #" + (depth% - d% + 1) + " - Connection failed! Reason:" + Mid$(txt$, Instr(txt$, " ", Instr(txt$, " ") + 2))
						CloseTCPStream stream%
						stream% = False
						Return stream%
					EndIf
				EndIf
			Wend
			
			; Clear buffer
			While ReadAvail(stream%)
				ReadLine$(stream%)
			Wend
		Next
	Else
		DebugLog this\host$ + ":" + this\port% + " - Connectuion failed!"
	EndIf
	
	Return stream%
End Function

Function PingProxies(check_bandwidth% = True, sort% = True)
	Local bank% = CreateBank(128)
	
	For this.proxy = Each proxy
		DebugLog this\host$ + ":" + this\port% + " - Connecting..."
		ping% = MilliSecs()
		stream% = OpenTCPStream(this\host$, this\port%)
		this\ping% = MilliSecs() - ping%
		If stream%
			WriteLine stream%, "GET <a href="http://www.google.com/" target="_blank">http://www.google.com/</a> HTTP/1.1"
			WriteLine stream%, "Host: " + this\host$
			WriteLine stream%, "User-Agent: MultiProx"
			WriteLine stream%, "Connection: Close"
			WriteLine stream%, ""
			
			If check_bandwidth%
				received% = 0
				tim% = MilliSecs()
				While Not Eof(stream%)
					avail% = ReadAvail(stream%)
					If avail% > BankSize(bank%) Then avail% = BankSize(bank%)
					If avail% Then received% = received% + ReadBytes(bank%, stream%, 0, avail%)
				Wend
				
				this\bandwidth% = Int(received% / ((MilliSecs() - tim%) / 1000.0))
				
				DebugLog this\host$ + ":" + this\port% + " - Ping: " + this\ping% + " Speed: " + Int(this\bandwidth% / 1024.0) + "KB/s"
			Else
				DebugLog this\host$ + ":" + this\port% + " - Ping: " + this\ping% + " Speed: N/A"
			EndIf
			
			CloseTCPStream stream% 
		Else
			DebugLog this\host$ + ":" + this\port% + " - Failed!"
		EndIf
	Next
	
	If sort%
		For this.proxy = Each proxy
			For that.proxy = Each proxy
				If this\ping < that\ping Then
					tmp$ = this\host$
					this\host$ = that\host$
					that\host$ = tmp$
					
					tmp$ = this\port%
					this\port% = that\port%
					that\port% = Int(tmp$)
					
					tmp$ = this\ping%
					this\ping% = that\ping%
					that\ping% = Int(tmp$)
					
					tmp$ = this\bandwidth%
					this\bandwidth% = that\bandwidth%
					that\bandwidth% = Int(tmp$)
				EndIf
			Next
		Next
	EndIf
	
	FreeBank bank%
End Function

Function AddProxy(host$, port% = 80)
	this.proxy = New proxy
		this\host$ = host$
		this\port% = port%
		this\ping% = -1
		this\bandwidth% = -1
End Function


Pretty useful stuff, thanks.

I've ran into a problem with proxy connection. It connects fine to HTTP server but FTP servers doesn't seem to be compatible. Are there some limitations for that?

I have no idea. Maybe one for the forums coding section.