






Hotspots: Admin Pages | Turn-in Site |
Current Links: Cases Final Project Summer 2007
Down and dirty Commanche basics
This was to be a "how to make Commanche work with 3.8" tutorial, but the packages from SqueakMap seem to work just fine now.
Instead, I will give you a very basic framework to set up some webserver-like functionality in Squeak. I'm not talking about serving files or a hello world page. That is the bollocks I've found and it is not all that helpful. I'll teach you how to parse requests in a simple, yet effective way, and give you a somewhat theoretical framework to implement these ideas in order to serve up either static or dynamic pages, your choice.
But, first things first.
Lets set up Commanche!
- Get squeak and the latest 3.8 image.
- Drag the image onto the executable and squeak should start.
- Click any blank spot on the deskop and choose open like this:

- Next, select the Package Loader, like this:

- Now, what you should be seeing is the Package Loader. Look at the two similar looking panes on the left side. You are looking for packages in the top pane.

- Now, select the following packages IN THIS ORDER:
- Dynamic bindings (1.2, it should be the default)
- KomServices (1.1.2, it should also be the default)
- KomHttpServer (7.0.3, yes, it is the default, too Timmy.)
- You are good to go, but you probably want to save your state. Saving as an image is fine, and everything will be there. However, what if you want to file-out so you can share and/or turn in your goodness without having to install everytime? YOU CANNOT MERELY FILEOUT THE THREE PACKAGES YOU INSTALLED! This was a source of endless frustration for me, because Commanche puts its sticky tendrils everywhere. In order to successfully file out your changes and a working Commanche setup, you need to . . .
File Out The Super Secret Commanche Dependencies!
- This part is absolute madness, but when you are done, you will save yourself the hassle of installing Kommanche over and over again when you are testing with a clean install.
- File out the following categories:
- DynamicBindings
- KomServices
- KomHttpServer-Protocol
- KomHttpServer-Modules
- KomHttpServer-Kernel
- BlockContext
- MessageSend
- Object
- Process
- String
- TimeStamp
- Form
- ContexttPart
- NetworkHost
- Note that these are numbered? They are numbered for a reason These need to be filed in in the EXACT SAME ORDER as listed here! Don't screw around on this one, or you will have random bugs that will take forever to track down! The best way to do this is to prefix every .st fileout with a number like 00, 01, etc. When you select them all to filein, they will be filed in in order, assuming the file you are dragging in is the first one. Now the fileout folder look something like this:

File Out Your Project
- Now you can file out your project (if you have one at this point). If your project depends on Kommanche, filein your project AFTER you filein the number-prefixed files. This shouldn't be a problem, since the order-sensitive categories are numbered, unless your classes start with a number. Now your fileout folder should look something like this:

- W00T! You have a working, portable Commanche framework.
Making a Webserver
- Alright! You made it this far, now it gets more interesting and less tedious. First, let's run by the barebones, mostly usesless code samples found throughout the KomWhatever Class comments:
| ma |
ma := ModuleAssembly core.
ma documentRoot: FileDirectory default fullName.
ma directoryIndex: 'index.html index.htm'.
ma serveFiles.
(HttpService startOn: 8080 named: 'Example') plug: ma rootModule
That would be a rather worthless http-based file server. I'm sure your projects will require something more . . . sophisticated.
- The requitiste "Hello World example:
| ma |
ma := ModuleAssembly core.
ma addPlug:
[ :request |
HttpResponse fromString: 'Hello world!'].
(HttpService startOn: 8080 named: 'Example') plug: ma rootModule.
I can see by the sneering gesture on your face that you are not that impressed. Neither was I. That's great that I can start a server and it says hello world back to me all day long, but it would be nice if it were useful.
No problem. Here's the word on what you need to know.
- a ModuleAssembly is what the actual server is, even though it doesn't sound anything remotely like something you would call a server.
- the addPlug: message in the ModuleAssembly defines a behaviour for reacting to an incoming request. It is best served a block or a class that can return a block.
- a request is something that the ModuleAssembly pukes out, it is basically the http request from the browser. You can do nifty things with it, if you like, like parsing it, determining the doctype, getting the url, etc.
- a HttpResponse is a response to the request. To get an idea of what kinds of things constitute a response, look at the HttpResponse class, and its class methods. Most, if not all of these methods do all the translation work for you, i.e. they format the Squeak-specific object into something that is HTML renderable. I'll list some of the more important and easy to use ones here.
- current - Current returns the current sesssion, if you enable such things in the ModuleAssembly.
- fromFileStream - Returns an HttpResponse from a Squeak-created file stream.
- fromURL - Returns a url, for your static or php or javascript enabled pages.
- redirectTo - Redirects you to the url that you fed in as a string. I found it HIGHLY useful to debug site logic when determining if Squeak was to blame. If redirectTo: aUrl works, then the problem is in your Squeak code, not your HTML.
- fromString - The Swiss Army knife of HttpResponses. You can return a string with the properly formed HTML of a page inside it, and there you go, the page is served.
Make it Happen
- Okay, all those useful things are not that useful if you don't know what to do with them. So I'll give you a better example than what you see in the Squeak Documentation. It won't run your project for you, but you should have a decent idea of what to do next, especially if someone in your group knows a little HTML or PHP or Javascript. I will present the classes in their entirety, then I'll break them down for you, if it isn't clear enough already.
The classes
- Server and ResponseProcessor
- The Server really needs just two main methods, it merely sets up an instance of the ModuleAssembly, and returns a HttpProcessor.
Object subclass: #SPServerLauncher
instanceVariableNames: 'theServer theProcessor'
classVariableNames: ''
poolDictionaries: ''
category: 'SqueakPoint-Server'
initialize
super initialize.
"The server is really just a Module Assembly."
theServer := ModuleAssembly core.
theServer trackSessions. "enable sessions"
theServer sessionTimeout: 30. "set session timeout to 30 minutes"
theProcessor := SPhttpProcessor new. "initializing the HTTP Processor"
"adding a plug (action) to the server on the specified port."
theServer addPlug:
[ :request |
theProcessor processHttpRequest: request].
(HttpService startOn: 8080 named: 'd1ld0') module: theServer rootModule.
processor
"returns the processor. for darkportal and its freakin potatoes."
^ theProcessor.
- ResponseProcessor returns some sort of response to a client request.
Object subclass: #SPhttpProcessor
instanceVariableNames: 'potato'
classVariableNames: ''
poolDictionaries: ''
category: 'SqueakPoint-Server'
initialize
"nothing to see here move along"
super initialize.
processHttpRequest: aRequest
"processes an HTTP request to see if an image or a form needs to be served.
passes the url to the appropriate object for retrieval."
| url formdata |
url := aRequest url copyFrom: 1 to: aRequest url size.
formdata := Dictionary new.
formdata addAll: (aRequest getFields copy).
formdata addAll: (aRequest postFields copy).
Transcript show: url; cr.
((url endsWith: '.jpg') or: [url endsWith: '.png'])
ifTrue: [
^(Form fromFileNamed: tard.png) asHttpResponseTo: aRequest.
].
(url endsWith: '.Pr0n")
ifTrue: [
^(HttpResponse redirectTo: 'http://www.slaaonline.org/').
].
^HttpResponse fromString: 'I screwed up. I expected you to ask for an image, which I would have served, or some pr0n, in which case I would have sent you to a sexual addiction help site. Unfortunately, I don't know what you asked, so this is what you get this text.'
Try it!
- Install the above code into your squeak image, run SPServerLauncher new. Now open a webbrowser, and go to http://localhost:8080. You should get the last HttpResponse in the processor code above (the string about being sorry that I can only server images or a sexual addiction url).
- This means the url you requested fell through the ifTrue: statements parsing the url in the processor.
- Now put a .jpg or .png file in your Squeak working folder. Let's say you put in a picture of my brother-in-law called 'tard.png'. Now point your browser to http://localhost:8080/tard.png, or anything that ends in png or jpg. Awesome! now you see a tard in your browser!
- This is because the url was parsed in the processor, looking at the last few letters. if they are png or jpg, that ifTrue: statement gets executed. I would tell you how to get it to serve any image based on the name requested, but I don't want to give away everything. (Hint: try to tokenize the url as a string, based on slashes)
- Now try my debugging statement. Point your browser to http://localhost:8080/gimme.the.pr0n. Awesome! You are a sex addict and your web server is pointing you toward a 12-step program that can help you.
- This is because the url was found to end in pr0n, so the response is a redirection to another site.
This should be everything you need to get up and running with Commanche. If you want to know more about our implementation, check out Team T34M's M5.
Links to this Page
- Cases last edited on 30 July 2011 at 2:33 am by r59h132.res.gatech.edu
- Patrick Burns last edited on 29 July 2006 at 6:37 am by fsk22.eastnet.gatech.edu