Examples

Talking to the browser

14 Talking to the browser.celsrc
-.-
	Talking to your browser
	
	In this example we show a simple example of how a cellspeak program can act as a server
	for the browser.
	
	To run this example instantiate BrowserTest and the open your browser and in the URL box
	type http://hostname:27524/sayhello where hostname is the name of your system or its ip address.
	
	In stead of /sayhello you can also try /green or /CellSpeak
	
-.-
use Windows, Math, Strings, Editor, System
use HTTPTypes

-- The cel that creates the server
design BrowserTest is
	cell Window
	constructor is 	
		-- Create a window for informative output
		Window = create MenuWindow("Interfacing with the browser")
		
		-- send a message to the system to set stdout, so others can use it as well	
		system <- stdout.Set(Window)
		
		-- And create a server that listens on port 27524..
		create ServerDesign("27524")		
	end
end

-- The server replies to requests from the browser
design ServerDesign(ansi Port) is 
	cell ConxMgr			-- The connection manager
	keep Port				-- keep the port number
	cell Client				

	constructor is 
		-- The server needs the connection manager
		system <- Service.Get("ConxMgr")	
	end
	
	destructor is 
		-- stop listening to the port
		ConxMgr <- HTTP.Stop.Listening(Port)
	end

	on Service.Provider(ansi Service, cell Provider) do	
		-- check that we have received the right service - otherwise yield
		Service is "ConxMgr" ? ConxMgr = Provider : yield
		
		-- We tell the connection manager that we want to listen for incoming connections
		ConxMgr <- TCPIP.Listen(Port)
		
		-- Inform about the status
		system <- println("Waiting for clients...")
	end
	
	-- we also get a message when someone wants to connect with us
	on TCPIP.Accept(ConxClass Conx) do
		-- We specify the protocol to be used over the link - we will handle the link ourselves
		ConxMgr <- Set.Protocol( Conx, "HTTP", self )
		
		-- inform 
		system <- println("Server [self]: Connection request [Conx] accepted")
	end	
	
	-- The connection manager replies with the protocol ready message - Client is the remote system
	on HTTP.Ready( cell Client ) do	
		keep Client
		system <- println("Protocol is ready")
	end 
		
	interface HTTP is
		
		-- We received a get request
		on GET(ansi URI, ansi Version, Header[] Headers, byte[] Content) do	
			ansi 	MyMessage				-- to make a reply message
			Header  ResponseHeaders[]		-- we wil use these for the reply
			byte[]  StyleSheet, HomePage	-- buffers for files
			int 	Error
	
			-- inform
			system <- println("Server [self]: Client [sender] GET request URI=[URI] Version=[Version]")
			
			-- Print the headers
			for each Header in Headers do
				system <- println("Header    [Header.Name]: [Header.Value]")
			end
			
			-- based on the URI we give a reply to the browser
			-- In a more involved application we could start a server for each incoming request
			switch URI 
			
				-- a nice blue welcoming page ..
				case "/sayhello":
								
					-- Make a message
					MyMessage = "\-<html>
								<head><title>CellSpeak Server Test</title></head>
								<body bgcolor=\"lightblue\">
								<center><h1>Hello Browser</h1>
								<p>This is a simple example of how to interact with the browser. </p>
								<p>Because CellSpeak is a message based language, it is easy to make a server.</p>
								</center>
								</body>
								</html>"

					-- The HTTP headers that we want to use for this response
					ResponseHeaders = [	[ "Date", HTTPDate()], 
										[ "Content-Type", "text/html" ], 
										[ "Connection", "keep-alive"],
										[ "Content-Length", "[MyMessage.len()]" ]  ]
					
					-- Now we send a reply via the cell that represents the remote client
					sender <- HTTP.RESPONSE("HTTP/1.1", "200", "OK", ResponseHeaders, MyMessage)
					
				-- but we also have a green page 
				case "/green" :
	
					-- Make a message
					MyMessage = "\-<html>
								<head><title>CellSpeak Server Test</title></head>
								<body bgcolor=\"lightgreen\">
								<center><h1>Another page</h1></center>
								<hr><center>This page is green.</center>
								</body>
								</html>"
								
					-- The headers 
					ResponseHeaders = [	[ "Date", HTTPDate()], 
										[ "Content-Type", "text/html" ], 
										[ "Content-Length", "[MyMessage.len()]" ]  ]
					
					-- Now we send a reply
					sender <- HTTP.RESPONSE("HTTP/1.1", "200", "OK", ResponseHeaders, MyMessage)
					
				-- a CellSpeak page
				case "/cellspeak" :
								
					-- read the homepage 
					Error, HomePage = File.Read("CellSpeak.html")												
					Error ? system <- println("Error reading file [Error]") & yield 
					
					ResponseHeaders = [	[ "Date", HTTPDate()], 
										[ "Content-Type", "text/html" ], 
										[ "Content-Length", "[nel HomePage]" ]  ]		

					-- Now we send a reply
					sender <- HTTP.RESPONSE("HTTP/1.1", "200", "OK", ResponseHeaders, HomePage)		

				-- The browser will also ask for the style sheet
				case "/CellSpeak.css" :	

					-- Get the stylesheet 
					Error, StyleSheet = File.Read("CellSpeak.css")			
					Error ? system <- println("Error reading file [Error]") & yield 
					
					ResponseHeaders = [	[ "Date", HTTPDate()], 
										[ "Content-Type", "text/css" ], 
										[ "Content-Length", "[nel StyleSheet]" ]  ]		

					-- Now we send a reply
					sender <- HTTP.RESPONSE("HTTP/1.1", "200", "OK", ResponseHeaders, StyleSheet)						
					
				-- sorry ..
				default :
						
					-- Make a message
					MyMessage = "\-<html>
								<head><title>CellSpeak Server Test</title></head>
								<body bgcolor=\"red\">
								<center><h1>The dreaded 404 page</h1></center>
								<hr><center>We're sorry, we could not find what you are looking for.</center>
								</body>
								</html>"
					
					-- The headers
					ResponseHeaders = [	[ "Date", HTTPDate()], 
										[ "Content-Type", "text/html" ], 
										[ "Content-Length", "[MyMessage.len()]" ]  ]
					
					-- Now we send a reply
					sender <- HTTP.RESPONSE("HTTP/1.1", "404", "Not Found", ResponseHeaders, MyMessage)
			end	
		end
	interface end
end