Thanks for the guides. I started to use types and this is the current code i've made:
Strict
Const RemoteFileCRLF:String = Chr(13) + Chr(10)
Const RemoteFileUserAgent:String = "Transporter"
Const RemoteFileTimeOut:Int = 5 * 1000
Type TRemoteFile
Field url:String, port:Int
Field filename:String, size:Int
Field socket:TSocket, stream:TSocketStream
Field error:String
Function Open:TRemoteFile(url:String, port:Int = 80, postdata:String = "", header:String = "")
Local file:TRemoteFile = New TRemoteFile
Local protocol:String = Sector(url, ":", 0)
Local host:String = Sector(url, "/", 2)
Local path:String = "/" + Sector(url, "/", 3, True)
' Check for port in server name
If Instr(host, ":") Then
port = Int(Sector(host, ":", 1))
host = Sector(host, ":", 0)
EndIf
Local server:String = "www." + Sector$(host$, ".", Sectors%(host$, ".") - 1) + "." + Sector$(host$, ".", Sectors%(host$, "."))
file.url = url
file.port = port
file.error = ""
file.filename = Sector(path, "/", Sectors(path, "/"))
file.socket = CreateTCPSocket:TSocket()
BindSocket(file.socket, 0)
' Connect to server
Local connection:Int = ConnectSocket(file.socket, HostIp(server), port)
If Not connection Then connection:Int = ConnectSocket(file.socket, HostIp(host), port)
If connection
file.stream = CreateSocketStream:TSocketStream(file.socket)
Select protocol
Case "http"
Local txt:String = ""
If Len(postdata) > 0 Then txt :+ "POST " + path + " HTTP/1.1" + RemoteFileCRLF Else txt :+ "GET " + path + " HTTP/1.1" + RemoteFileCRLF
txt :+ "Host: " + host + RemoteFileCRLF
txt :+ "User-Agent: " + RemoteFileUserAgent + RemoteFileCRLF
If Len(header) > 0 Then txt :+ header + RemoteFileCRLF
If Len(postdata) > 0 Then txt :+ "Content-Type: application/x-www-form-urlencoded" + RemoteFileCRLF + "Content-Length: " + Len(postdata) + RemoteFileCRLF
txt :+ "Connection: Close" + RemoteFileCRLF
txt :+ ""
If Len(postdata) > 0 Then txt :+ RemoteFileCRLF + postdata
WriteLine(file.stream, txt)
Print txt
' Check response
Local tim:Int = MilliSecs()
Repeat
If RemoteReadAvail(file)
txt = ReadRemoteLine(file)
If Sector(txt, "/", 0) = "HTTP"
If Int(Sector(txt, " ", 1)) => 303 Then file.error = "HTTP Error: " + txt
Exit
EndIf
EndIf
If (MilliSecs() - tim) => RemoteFileTimeOut Then file.error = "No response from server!"
Forever
Local cmd:String, value:String
If file.error = ""
Repeat
If RemoteReadAvail(file)
txt = ReadRemoteLine(file)
If txt$ = "" Then Exit
cmd = Sector(txt, ":", 0)
value = Sector(txt, " ", 1)
Select cmd
Case ""
Return file
Case "Content-Disposition"
Local i:Int, subtxt:String, subvalue:String
For i = 0 To Sectors(value, ";")
subtxt = Trim(Sector(value, ";", i))
subvalue = Sector(subtxt, "=", 1)
Select Lower(Sector(subtxt, "=", 0))
Case "filename"
file.filename = subvalue
End Select
Next
Case "Content-Length"
file.size = Int(value$)
End Select
EndIf
Forever
EndIf
Case "ftp"
End Select
Else
file.error = "Unable to connect to " + file.url + ":" + file.port
EndIf
Return file
End Function
Method ReadAvail:Int()
Return SocketReadAvail(socket)
End Method
Method RemoteLine:String()
Return ReadLine(stream)
End Method
Method LastError:String()
Return error
End Method
Method Name:String()
Return filename
End Method
Method FSize:Int()
Return size
End Method
End Type
Local file:TRemoteFile = OpenRemoteFile("http://www.rate.ee/")
If RemoteFileError(file) = ""
While Not RemoteReadAvail(file)
Wend
While RemoteReadAvail(file)
Print RemoteFileName(file) + " [" + RemoteFileSize(file) + "] "+ " -> " + ReadRemoteLine(file)
Wend
Else
Notify RemoteFileError(file)
EndIf
End
Function OpenRemoteFile:TRemoteFile(url:String, port:Int = 80, postdata:String = "")
Return TRemoteFile.Open(url, port, postdata)
End Function
Function RemoteReadAvail:Int(file:TRemoteFile)
Return file.ReadAvail()
End Function
Function ReadRemoteLine:String(file:TRemoteFile)
Return file.RemoteLine()
End Function
Function RemoteFileError:String(file:TRemoteFile)
Return file.LastError()
End Function
Function RemoteFileName:String(file:TRemoteFile)
Return file.Name()
End Function
Function RemoteFileSize:Int(file:TRemoteFile)
Return file.FSize()
End Function
Function Sector:String(txt:String, separator:String, sector:Int, toend:Int = 0)
Local result:String = "", occ:Int, i:Int
For i:Int = 1 To Len(txt)
If Mid(txt, i, 1) = separator
occ :+ 1
If toend And occ > sector Then result = result + Mid(txt, i, 1)
Else
If occ => sector Then result = result + Mid(txt, i, 1)
EndIf
If Not toend Then If occ > sector Then Exit
Next
Return result
End Function
Function Sectors:Int(txt:String, needle:String)
Local occ:Int = 0, i:Int
For i:Int = 1 To Len(txt)
If Instr(txt, needle, i)
occ = occ + 1
i = Instr(txt, needle, i)
Else
Exit
EndIf
Next
Return occ
End Function
Function
OpenRemoteFile:TRemoteFile(url:String, port:Int = 80, postdata:String = "") can be used to open a remote/online file. After that you'll need to check for errors:
RemoteFileError:String(file:TRemoteFile) and then you can start to read with
ReadRemoteLine:String(file:TRemoteFile)