Code archives/Networking/Simple webserver

This code has been declared by its author to be Public Domain code.

Download source code

Simple webserver by ozak2005
This is a simple example of a webserver in BlitzMax.
Note that only one file is served at a time, so without changes it won't be good at serving large files.
For simple pages with images etc. it works well.

Note that it's only a sample. Suggestions for improvements is in the comments section at the top.

Don't forget to compile as no gui app :)

To test, just type http://localhost in any browser.
Remember to at least have an index.html file or you'll get a file not found error.
' Simple BlitzMax webserver by Odin Jensen 
' Exercise: Save all client sockets in list, update them a little each frame and then disconnect.
'           That will allow multiple connections without any delay like a real webserver :)

' EOL define
Const EOL:String = "~r~n"

' Create socket
Global mainSock:TSocket = CreateTCPSocket()

' Bind socket to port 80 (web port)
If (Not BindSocket(mainSock, 80))

	Print("Error binding socket. Someone might already be using that port.")
	End

End If

' Listen on socket
SocketListen(mainSock)

Print("Server online at port 80")

' Main loop
While (Not KeyHit(KEY_ESCAPE))

	' Check for connections
	Local clientSock:TSocket = SocketAccept(mainSock, 0)	

	' Did we get a connection?
	If (clientSock <> Null)
	
		' Print IP
		Print("Client '"+DottedIP(SocketRemoteIP(clientSock))+" connected!")
		
		' Create stream for client
		Local clientStream:TSocketStream = CreateSocketStream(clientSock)
		
		Print("")
		
		' Get first line
		Local line:String = ReadLine(clientStream)
		Print(line)
		
		' Grab request
		Local req:String = line[0..line.findLast(" ")]

		' Write rest of request		
		While (line <> "")
		
			line = ReadLine(clientStream)
			Print(line)
			
		Wend
		
		' Output client request
		Print("Client wants to: " + req)		
		
		' Do we have a get request?
		If (req.find("GET") <> -1)
		
			' Ok. Attempt to find file
			Local fileName:String = req[4..req.length]
			Print("Client requested file: " + fileName)
			
			' Is it root?
			If (fileName = "/")
			
				' Yes. Send index 
				fileName = "/index.html"
			
			End If
			
			' Fix file (remove /)
			fileName = fileName[1..fileName.length]
			
			
			' Try to open
			Local file:TStream = ReadStream(fileName)
			
			' Failed?
			If (file = Null)
			
				WriteLine(clientStream, "HTTP/1.0 404 Not found" + EOL)
				WriteLine(clientStream, EOL)
				WriteLine(clientStream, "404: " + fileName + " not found!")
			
			Else
			
				
				' Send stream
				Local bytes:Byte[512]
				While (Not Eof(file))
				
	
					' NOTE! Only byte read/write here so binaries works as expected
					Local read:Int = file.readBytes(bytes, 512)
					clientStream.writeBytes(bytes, read)
				
				Wend
				
				' Close stream
				CloseStream(file)
			
			End If
		
		
		Else
		
			' Send unsupported request message
			WriteLine(clientStream, "HTTP/1.0 405 unsupported method type: " + EOL)
			WriteLine(clientStream, "405: Unsupported method type: " + req)
		
		End If
				
		
		' Disconnect client
		FlushStream(clientStream)
		CloseSocket(clientSock)
	
	End If

Wend

' Close main socket
CloseSocket(mainSock)

Comments

deps2005
Interesting. Thanks! :)


ShadowTurtle2005
I want PHP Support.


CoderLaureate2005
Why limit yourself to php? You could create a whole new web scripting language! ;)


Perturbatio2005
I want PHP Support.

It shouldn't be that hard to add PHP support actually, you just need to pass the page via the php program, capture it's output and then push it to the client.


ozak2005
Yeah. Adding PHP or doing your own plugin system should be easy from here.
I checked the server with a rather complex page and all loaded fast and worked fine.
But for file hosting, I'd store all clients in a list and send a little to'em each frame.
I'm sure this would be alot faster as most browsers use multiple threads for getting page content :)


Rook Zimbabwe2006
I want SQL support!!!


Andres2006
Without PHP there is no SQL support. When there will be PHP support there will be also SQL automatically. SQL is a separate server.


Luke1112010
Edit: I apologize its now been done by another person. Didnt see it. Will work off that version.


_PJ_2010

Edit: I apologize its now been done by another person. Didnt see it. Will work off that version.


Actually that's oftern an advantage with the code archives. Different approaches to a piece of code can be good for many reasons, such as

1) understanding how it works / ease of implementation into ones own code
2) additional or more comprehensive features
3) better optimisation options
4) a mutrual comparison of advantages and disadvantage, culminating hopefully in perhaps a hybrid of multiple versions which serves a purpose specific to the user.

As you stated "weorking from that version" is a clear indicationof how you might take the better parts of a version, and incorporate features or optimiosation thus making a better one all round.

Since code is always so specific when used by a third party (i.e. someone looking through the archives for a solution to a particular issue) then having more than one option can be a great thing :)

____________

Incidentally, I believe there's a very comprehensive SQL 'thing' in the code arcs :)


Code Archives Forum