; ------------------------------------------------------------------------ ; HeavyThing x86_64 assembly language library and showcase programs ; Copyright © 2015-2018 2 Ton Digital ; Homepage: https://2ton.com.au/ ; Author: Jeff Marrison <firstname.lastname@example.org> ; ; 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'