TCP stream though proxy (chaining) functions

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

The forum is locked. These are the original blitzbasic.com forums, kept so they can still be read. No new topics, replies or edits can be made here. To join in, head over to the Blitz3D+ forums.

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.