'
' HTTP
' version 0.1
' (c) 2011 Stefan Wurzinger
'

#Include Once "win/winsock.bi"

#Include Once "url.bi"
#Include Once "net.bi"
#Include Once "general.bi"

Const RECVBUFFLEN = 8192

Declare Function getHTTP OverLoad (ByRef url As URL, ByRef outp As String) As String
Declare Function getHTTP OverLoad (ByRef url As String, ByRef outp As String) As String
Declare Function getHTTP OverLoad (ByRef url As String, ByRef params As String, ByRef outp As String) As String

Declare Function postHTTP OverLoad (ByRef url As URL, ByRef dat As String, ByRef dat_type As String = "application/x-www-form-urlencoded", ByRef outp As String) As String
Declare Function postHTTP OverLoad (ByRef url As String, ByRef dat As String, ByRef dat_type As String = "application/x-www-form-urlencoded", ByRef outp As String) As String



Function getHTTP OverLoad (ByRef url As URL, ByRef outp As String) As String

	Dim ip As Integer
  Dim s As SOCKET
  
  'resolve host
  ip = resolveHost(url.Host)
  If ip = 0 Then Return "Error: resolveHost failed"
	
  'open socket
  s = OpenSocket(AF_INET, SOCK_STREAM, IPPROTO_TCP)
  If(s = 0) Then Return "Error: " & WSAGetLastError() & " Calling: socket()"
    
	'connect to host
	Dim sa As sockaddr_in
	
	sa.sin_port	= htons(80)
	sa.sin_family = AF_INET
	sa.sin_addr.S_addr = ip
	
	If (connect(s, Cast(PSOCKADDR, @sa), Len(sa)) = SOCKET_ERROR) Then
		Dim tmp_errM As String = "Error: " & WSAGetLastError() & " Calling: connect()"
		closesocket(s)
		Return tmp_errM
	End If
    
  'send HTTP request
  Dim sendbuffer As String
	sendBuffer = "GET " + url.URI
	If url.Query <> "" Then sendBuffer &= "?" + url.Query
	sendBuffer &= " HTTP/1.0" + CRLF + _
				 "Host: " + url.Host + CRLF + _
				 "Connection: close" + CRLF + _
				 "User-Agent: FreeBasic Client" + CRLF + _
				 CRLF
				 
  If(send(s, sendBuffer, Len(sendBuffer), 0) = SOCKET_ERROR) Then
		Dim tmp_errM As String = "Error: " & WSAGetLastError() & " Calling: send()"
		closesocket(s)
		Return tmp_errM
	End If
    
  'receive until connection is closed
  Dim recvbuffer As ZString * RECVBUFFLEN+1
  Dim bytes As Integer
  
  outp = ""
  Do 
  	bytes = recv(s, recvBuffer, RECVBUFFLEN, 0)
  	If bytes <= 0 Then Exit Do
  	outp += Left(recvbuffer, bytes)
  Loop
  
  Dim posHeaderEnd As Integer
  posHeaderEnd = InStr(outp, CRLF & CRLF)
  If posHeaderEnd > 0 Then outp = Mid(outp, posHeaderEnd+4)
                         
	'close socket
	shutdown(s, 2)
	closesocket(s)
	
End Function

Function getHTTP OverLoad (ByRef url As String, ByRef outp As String) As String
	Return getHTTP(ExtractURL(url), outp)
End Function

Function getHTTP OverLoad (ByRef url As String, ByRef params As String, ByRef outp As String) As String
	Dim tmpURL As URL = ExtractUrl(url)
	tmpURL.Query = URLEncode(params)
	Return getHTTP(tmpURL, outp)
End Function

Function postHTTP OverLoad (ByRef url As URL, ByRef dat As String, ByRef dat_type As String = "application/x-www-form-urlencoded", ByRef outp As String) As String

	Dim ip As Integer
  Dim s As SOCKET
  
  'resolve host
  ip = resolveHost(url.Host)
  If ip = 0 Then Return "Error: resolveHost failed"
	
  'open socket
  s = OpenSocket(AF_INET, SOCK_STREAM, IPPROTO_TCP)
  If(s = 0) Then Return "Error: " & WSAGetLastError() & " Calling: socket()"
    
	'connect to host
	Dim sa As sockaddr_in
	
	sa.sin_port	= htons(80)
	sa.sin_family = AF_INET
	sa.sin_addr.S_addr = ip
	
	If (connect(s, Cast(PSOCKADDR, @sa), Len(sa)) = SOCKET_ERROR) Then
		Dim tmp_errM As String = "Error: " & WSAGetLastError() & " Calling: connect()"
		closesocket(s)
		Return tmp_errM
	End If
    
  'send HTTP request
  Dim sendbuffer As String
	sendBuffer = "POST " + url.URI
	If url.Query <> "" Then sendBuffer &= "?" + url.Query
	sendBuffer &= " HTTP/1.1" + CRLF + _
				 "Host: " + url.Host + CRLF + _
				 "Connection: close" + CRLF + _
				 "User-Agent: FreeBasic Client" + CRLF + _
				 "Content-Type: " + dat_type + CRLF + _
				 "Content-Length: " + Str(Len(dat)) + CRLF + _
				 CRLF + dat
				 
  If(send(s, sendBuffer, Len(sendBuffer), 0) = SOCKET_ERROR) Then
		Dim tmp_errM As String = "Error: " & WSAGetLastError() & " Calling: send()"
		closesocket(s)
		Return tmp_errM
	End If
    
  'receive until connection is closed
  Dim recvbuffer As ZString * RECVBUFFLEN+1
  Dim bytes As Integer
  
  outp = ""
  Do 
  	bytes = recv(s, recvBuffer, RECVBUFFLEN, 0)
  	If bytes <= 0 Then Exit Do
  	outp += Left(recvbuffer, bytes)
  Loop
  
  Dim posHeaderEnd As Integer
  posHeaderEnd = InStr(outp, CRLF & CRLF)
  If posHeaderEnd > 0 Then outp = Mid(outp, posHeaderEnd+4)
                         
	'close socket
	shutdown(s, 2)
	closesocket(s)
	
End Function

Function postHTTP OverLoad (ByRef url As String, ByRef dat As String, ByRef dat_type As String = "application/x-www-form-urlencoded", ByRef outp As String) As String
	Return postHTTP(ExtractUrl(url), dat, dat_type, outp)
End Function
