; ------------------------------------------------------------------------
; HeavyThing x86_64 assembly language library and showcase programs
; Copyright © 2015-2018 2 Ton Digital
; Homepage: https://2ton.com.au/
; Author: Jeff Marrison <jeff@2ton.com.au>
;
; This file is part of the HeavyThing library.
;
; HeavyThing is free software: you can redistribute it and/or modify
; it under the terms of the GNU General Public License, or
; (at your option) any later version.
;
; HeavyThing is distributed in the hope that it will be useful,
; but WITHOUT ANY WARRANTY; without even the implied warranty of
; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
; GNU General Public License for more details.
;
; You should have received a copy of the GNU General Public License along
; with the HeavyThing library. If not, see <http://www.gnu.org/licenses/>.
; ------------------------------------------------------------------------
;
; rwasa.asm: Rapid Web Application Server in Assembler :-) haha
;
; Burning Purpose: Using the webserver architecture of the HeavyThing
; library, provide normal HTTP[s] web serving w/ optional fastcgi,
; and provide a simple example application that allows very easy
; custom application handling from within this assembler environment.
;
; While the example application's assembly language hook doesn't DO
; anything, copying this, modifying the webhook and recompiling is
; basically all you'd have to do. (This demo piece just returns an
; unexciting web response for .asmcall hooks, see inline comments
; below for further details, as well as the -funcmatch startup option
; that overrides the .asmcall matching)
;
; Further, in its standalone "showcase piece" form, it nicely provides
; full normal webserver support.
;
; NOTE Re: our argument parsing/config building goods, while we do
; catch some operational issues with the arguments we are passed, it
; is more a matter of "garbage in or nonsensible order, etc" == undefined
; results.... haha, used as intended, it is fine, YMMV :-)
;
; See https://2ton.com.au/rwasa for the full commentary/docs.
;
include '../ht_defaults.inc'
include '../ht.inc'
include 'arguments.inc'
include 'worker.inc'
include 'master.inc'
; this is our main function call hook, as defined by _start.hookthemall
; it is called by the webserver layer with:
; rdi == webserver object, rsi == request url, rdx == mimelike request object
; per the webserver layer requirements, we must return one of:
; null: webserver will respond with a 404 automatically.
; -1 == webserver will sit there and do absolutely nothing
; or anything else is a properly formed mimelike response object (including
; preface line)
;
; for our demonstration purposes, we'll construct a simple text/plain return
falign
asmcall:
prolog asmcall
push rbx r12
; build a dynamic text reply first up
mov rbx, rsi
call buffer$new
mov rdi, rax
mov rsi, .stringpreface
mov r12, rax
call buffer$append_string
mov rdi, rbx
call url$tostring
mov rbx, rax
mov rdi, r12
mov rsi, rax
call buffer$append_string
mov rdi, rbx
call heap$free
mov rdi, r12
mov rsi, .stringreply
call buffer$append_string
; construct our return object
call mimelike$new
; set the http preface
mov rbx, rax
mov rdi, rax
mov rsi, .httppreface
call mimelike$setpreface
; set our content type
mov rdi, rbx
mov rsi, mimelike$contenttype
mov rdx, mimelike$textplain
call mimelike$setheader
; set our body to the UTF8 of our string
mov rdi, rbx
mov rsi, [r12+buffer_itself_ofs]
mov rdx, [r12+buffer_length_ofs]
call mimelike$setbody
; free our working buffer
mov rdi, r12
call buffer$destroy
; return our mimelike response
mov rax, rbx
pop r12 rbx
epilog
cleartext .stringpreface, 'Welcome to rwasa!',13,10,'URL: '
cleartext .stringreply, 13,10,'This is a native assembler function call hook.',13,10,13,10,'See https://2ton.com.au/rwasa for more information/documentation.',13,10
cleartext .httppreface, 'HTTP/1.1 200 rwasa reporting for duty'
public _start
falign
_start:
call ht$init
; Let the boring stuff handle argument parsing (which determines
; all of the initial configuration/etc and provides basic usage)
call arguments
; now, there is a list of webservercfg objects sitting in the
; global variable [configs], minimum count of 1 (the arguments
; function doesn't allow startup with zero configurations).
; So, our default demo action is to hook every webrequest for
; every single configuration that ends in .asmcall, such that
; any URL request to our webserver enviro whose path ends in
; same will call our do-nothin (note: .asmcall can be changed
; with the startup option -funcmatch)
mov rdi, [configs]
mov rsi, .hookthemall
call list$foreach
; start everything up
jmp masterthread
falign
.hookthemall:
; this is called by list$foreach with rdi == webservercfg object
; all we are doing is adding a function call hook attached
; to .asmcall (or whatever was specified with -funcmatch)
mov rsi, [funcmatch]
mov rdx, asmcall
call webservercfg$function_map
ret
include '../ht_data.inc'