=== REQUEST FOR CREATION === [To be converted to a Powerpoint Document] [args. no time left to do that. you'll have to live with a .txt file] WEBSERVER BOSS: "I want a completely new kind of webserver with fancy features and all. The basic version shall support the following:" The server shall listen on port 8080. Connections. Like in normal HTTP, a connection is established and a command is issued from the client (i.e., web browser). A command looks like this: (parenthesis indicate optional line) COMMAND PARAMS [VERSION] [Host: vir.tual.ho.st] [Cookie: key=value] [Session: $(ID)] $(EMPTY_LINE) Currently supported commands: GET|POST|SESSION|CREATE|DTP Currently supported version: HTTP20/0 Commands explained ====================================================================== SESSION ---------------------------------------------------------------------- SYNOPSIS: SESSION $(SESSION_ID) $(SESSION_ID) matches [A-Za-z0-9]+ The SESSION command creates a new session to be used for subsequent GET/POST requests. The webserver responds in one of the following ways: (only the number matters, the text is up to you) 200 SESSION CREATED 300 TEMPORARY ERROR, TRY AGAIN LATER 400 SESSION ALREADY EXISTS CREATE ---------------------------------------------------------------------- SYNOPSIS: CREATE $(USER) "$(FULLNAME)" $(PASSWORD) The CREATE command creates a user to be subsequently used to upload files. All files uploaded by $(USER) are accessible through http://url.to.webserver/~$(USER)/$(PATH) or http://$(USER).some.domain.foo/$(PATH) where $(PATH) specifies the relative path to the document. $(USER) matches [A-Za-z][A-Za-z0-9]+ $(FULLNAME) matches [^"]* $(PASSWORD) matches [-_A-Za-z0-9]+ $(USER) specifies the unix name for a new company client. $(USER) may use the created account to upload files. All uploaded content can be accessed by http://main.domain.foo/~$(USER)/$(PATH) or by http://$(USER).what.ever.domain.foo/$(PATH) The webserver responds in one of the following ways: (only the number matters, the text is up to you) 200 USER CREATED 300 USER EXISTS 400 USER COULD NOT BE CREATED DTP (Datei Transfer Protocol) ---------------------------------------------------------------------- SYNOPSIS: DTP UPLOAD $(USER) $(PASSWORD) $(PATH)\nLines: $(LINES)\n\n$(BASE64Content)\n DTP DOWNLOAD $(USER) $(PASSWORD) $(PATH)\n\n DTP MKDIRS $(USER) $(PASSWORD) $(PATH_TO_CREATE)\n\n DTP can be used by users created with the CREATE command to upload and download files, and to create subdirectories. The DOWNLOAD command should deliver any file as is, without interpreting or reencoding it. GENERIC ERROR MESSAGES 100 INVALID PARAMETERS 120 LOGIN INCORRECT MKDIRS ====== Create the specified path and all subpaths. Return values: 200 OK 300 FAILURE UPLOAD ====== The DTP command allows users to (up|down)load files to their webspace. $(PATH) is relative to the user's web root directory. The user may upload the following through this call. a) static html files; b) cgi scripts; c) fastcgi scripts; d) the virtual URL config file .urls. $(USER) is the unix name as specified at CREATE $(PASSWORD) is the password specified at CREATE $(LINES) is the number of lines of the BASE64 encoded file to upload $(BASE64Content) is the BASE64 encoded file to upload. After having read the empty line, the webserver responds with (only the number matters): 200 GO AHEAD 300 INVALID PATH 400 ERROR 500 LINES NOT SPECIFIED After having read $(LINES) lines, the webserver responds with: 200 Thank you, $(FULLNAME), for uploading the file 300 ENCODING ERROR 400 FOO GENERIC ERROR DOWNLOAD ======== After having read the empty line, the webserver responds with: 200 Thank you, $(FULLNAME), your file is $(LINES) line(s) long in encoded form. \n$(BASE64ENCODED_FILE) 300 PERMISSION DENIED 400 PERMISSION NOT GRANTED 500 HARD DRIVE FAULTY 600 I DON'T FEEL LIKE COMPLYING RITE NOW, TRY AGAIN 700 INVALID PATH GET / POST ---------------------------------------------------------------------- PARAMS: PATH to website PATH consists of two or three parts: /~hc /dir/subdir/ file.html HOSTINGCLIENT DIRECTORY FILENAME -- OR -- /~hc /virtual/path/123/with/foo HOSTINGCLIENT VIRTUAL PATH The HOSTINGCLIENT is the unix name of the user whose webspace is to be accessed. It may either be specified in the shown form '/~$(USER)' or implicit via virtual hosting. In the latter case, the /~$(USER) part can be omitted. Virtual hosts are in the form $(USER).foo.bar; only the leftmost part matters. DIRECTORY is the path to the static file or CGI script to be served. FILENAME is the filename of a static website (ending with .html) or a cgi script, ending (.cgi) VIRTUAL PATH is a path to a fastcgi; allowed VIRTUAL PATHs are specified using regular expressions in a file called '.urls' in the web root directory of a user. === DIFFERENCE BETWEEN GET AND POST === A POST request is forwarded to a CGI script by passing the filehandle to the cgi script after the $(EMPTY_LINE) has been read. GET requests do not involve passing of filehandles to CGI scripts === FORMAT OF THE .urls FILE === The urls file contains mappings between URLs and URL handlers. The .urls file resides in the web root directory of a client. ($(HOSTINGCLIENT)/.urls) All requests mapped by the .urls file are handled by the .ipy scripts. (ipy standing for Incompatible PYthon). All other requests are CGI requests or static HTML requests. The urls file is read linewise. Separator is TAB. Each line looks like: $(REGEXP) $(PATH_TO_HANDLER) $(FUNCTION) REGEXP is a regular expression. The first line with a regular expression that fully matches the URL is used. If no line applies, the request is a CGI request or a static file request. PATH_TO_HANDLER is relative to $(HOSTINGCLIENT). It may start with a slash, but does not have to. To give you an example: / /mainsite.ipy index /articles /article.ipy index /article/([0-9]+) /article.ipy viewarticle === The IPY (TM) language === This is a reduced syntax python language specifically designed for webhosting. ;-) An .ipy file has the following format: def function(request, response, db, session, stdin): FUNCTION_BODY def next_function(request, response, db, session, stdin): FUNCTION_BODY You don't have to support definition of custom classes. The language must support the following python constructs: - def - for - if The following builtin functions must be supported: - range USAGE AS IN PYTHON - log(s) LOG SPECIFIED STRING SOMEWHERE - isnull(exp) IS THE SPECIFIED EXPRESSION == null? ==== request, response, db, session, stdin ==== These objects must support the following methods: request: String getHTTPRequest() response: void setContentType(String contentType) db: void execute(String dbQuery) List query(String dbQuery) session: void put(String key, String value) String get(String key) stdin: boolean ready() String readLine() === String builder === This class is used to concatenate strings. Usage: foo = StringBuilder.new() foo.append("foo") foo.append("bar") foobar = foo.toString() === Ruby implicit FOOget() === Suppose a builtin class has a method getfoo(), it shall be callable by instance.getfoo() --AND-- instance.foo === Example === There's an example website in example/ === Flag distribution === The scorebot performs various tests at various times. Do not be surprised if your service is sometimes marked as broken, and sometimes not. === Problems === If you experience problems, it's best to analyze what the scorebot tires to do, and to look at the source code the scorebot provides. ===== MISCELLANEOUS ===== We will distribute our reference implementation not earlier than one hour before the CTF ends. (maybe later, though)