@@ -296,6 +296,43 @@ var Builtins_http = map[string]*env.Builtin{
296296 },
297297 },
298298
299+ // Example:
300+ // ; Inside a handler: w .Add-header 'set-cookie "a=1; Path=/; HttpOnly"
301+ // ; Inside a handler: w .Add-header 'vary "Accept-Encoding"
302+ // Args:
303+ // * writer: Native Go-server-response-writer object from HTTP handler
304+ // * name: Word representing the header name (e.g., 'set-cookie, 'vary)
305+ // * value: String value to add for the header
306+ // Returns:
307+ // * the response writer object for method chaining
308+ "Go-server-response-writer//Add-header" : {
309+ Argsn : 3 ,
310+ Doc : "Adds a custom HTTP header value in the response, preserving existing values for multi-value headers." ,
311+ Fn : func (ps * env.ProgramState , arg0 env.Object , arg1 env.Object , arg2 env.Object , arg3 env.Object , arg4 env.Object ) env.Object {
312+ switch writer := arg0 .(type ) {
313+ case env.Native :
314+ switch name := arg1 .(type ) {
315+ case env.Word :
316+ name_ := ps .Idx .GetWord (name .Index )
317+ switch value := arg2 .(type ) {
318+ case env.String :
319+ writer .Value .(http.ResponseWriter ).Header ().Add (name_ , value .Value )
320+ return arg0
321+ default :
322+ ps .FailureFlag = true
323+ return MakeArgError (ps , 3 , []env.Type {env .StringType }, "Go-server-response-writer//Add-header" )
324+ }
325+ default :
326+ ps .FailureFlag = true
327+ return MakeArgError (ps , 2 , []env.Type {env .WordType }, "Go-server-response-writer//Add-header" )
328+ }
329+ default :
330+ ps .FailureFlag = true
331+ return MakeArgError (ps , 1 , []env.Type {env .NativeType }, "Go-server-response-writer//Add-header" )
332+ }
333+ },
334+ },
335+
299336 // Example:
300337 // ; Inside a handler: w .Write-header 404
301338 // ; Inside a handler: w .Write-header 200
@@ -493,6 +530,148 @@ var Builtins_http = map[string]*env.Builtin{
493530 },
494531 },
495532
533+ // Example:
534+ // ; Inside a handler: req .Header? "authorization"
535+ // ; Inside a handler: req .Header? "content-type"
536+ // Args:
537+ // * request: Native Go-server-request object from HTTP handler
538+ // * name: String header name to retrieve (e.g., "authorization", "content-type")
539+ // Returns:
540+ // * string header value (empty string if header is missing)
541+ "Go-server-request//Header?" : {
542+ Argsn : 2 ,
543+ Doc : "Gets a header value from the HTTP request by name." ,
544+ Fn : func (ps * env.ProgramState , arg0 env.Object , arg1 env.Object , arg2 env.Object , arg3 env.Object , arg4 env.Object ) env.Object {
545+ switch req := arg0 .(type ) {
546+ case env.Native :
547+ switch name := arg1 .(type ) {
548+ case env.String :
549+ val := req .Value .(* http.Request ).Header .Get (name .Value )
550+ return * env .NewString (val )
551+ default :
552+ ps .FailureFlag = true
553+ return MakeArgError (ps , 2 , []env.Type {env .StringType }, "Go-server-request//header?" )
554+ }
555+ default :
556+ ps .FailureFlag = true
557+ return MakeArgError (ps , 1 , []env.Type {env .NativeType }, "Go-server-request//header?" )
558+ }
559+ },
560+ },
561+
562+ // Example:
563+ // ; Inside a handler: creds: req .Basic-auth?
564+ // ; user: creds |first
565+ // ; pass: creds |second
566+ // Args:
567+ // * request: Native Go-server-request object from HTTP handler
568+ // Returns:
569+ // * block with username and password strings when Basic Auth is present
570+ // * error when Basic Auth credentials are missing
571+ "Go-server-request//Basic-auth?" : {
572+ Argsn : 1 ,
573+ Doc : "Gets HTTP Basic Authentication credentials from the request as [username password]." ,
574+ Fn : func (ps * env.ProgramState , arg0 env.Object , arg1 env.Object , arg2 env.Object , arg3 env.Object , arg4 env.Object ) env.Object {
575+ switch req := arg0 .(type ) {
576+ case env.Native :
577+ username , password , ok := req .Value .(* http.Request ).BasicAuth ()
578+ if ! ok {
579+ ps .FailureFlag = true
580+ return MakeBuiltinError (ps , "Basic auth credentials are missing." , "Go-server-request//basic-auth?" )
581+ }
582+ pair := make ([]env.Object , 2 )
583+ pair [0 ] = * env .NewString (username )
584+ pair [1 ] = * env .NewString (password )
585+ return * env .NewBlock (* env .NewTSeries (pair ))
586+ default :
587+ ps .FailureFlag = true
588+ return MakeArgError (ps , 1 , []env.Type {env .NativeType }, "Go-server-request//basic-auth?" )
589+ }
590+ },
591+ },
592+
593+ // Example:
594+ // ; Inside a handler: req .Method?
595+ // ; equal { req .Method? } "GET"
596+ // Args:
597+ // * request: Native Go-server-request object from HTTP handler
598+ // Returns:
599+ // * string containing HTTP method (GET, POST, PUT, DELETE, ...)
600+ "Go-server-request//Method?" : {
601+ Argsn : 1 ,
602+ Doc : "Gets the HTTP request method." ,
603+ Fn : func (ps * env.ProgramState , arg0 env.Object , arg1 env.Object , arg2 env.Object , arg3 env.Object , arg4 env.Object ) env.Object {
604+ switch req := arg0 .(type ) {
605+ case env.Native :
606+ return * env .NewString (req .Value .(* http.Request ).Method )
607+ default :
608+ ps .FailureFlag = true
609+ return MakeArgError (ps , 1 , []env.Type {env .NativeType }, "Go-server-request//method?" )
610+ }
611+ },
612+ },
613+
614+ // Example:
615+ // ; Inside a handler: body: req .Read-body
616+ // ; Inside a handler: print body
617+ // Args:
618+ // * request: Native Go-server-request object from HTTP handler
619+ // Returns:
620+ // * string containing the request body
621+ "Go-server-request//Read-body" : {
622+ Argsn : 1 ,
623+ Doc : "Reads the HTTP request body as a string." ,
624+ Fn : func (ps * env.ProgramState , arg0 env.Object , arg1 env.Object , arg2 env.Object , arg3 env.Object , arg4 env.Object ) env.Object {
625+ switch req := arg0 .(type ) {
626+ case env.Native :
627+ data , err := io .ReadAll (req .Value .(* http.Request ).Body )
628+ if err != nil {
629+ ps .FailureFlag = true
630+ return MakeBuiltinError (ps , err .Error (), "Go-server-request//read-body" )
631+ }
632+ return * env .NewString (string (data ))
633+ default :
634+ ps .FailureFlag = true
635+ return MakeArgError (ps , 1 , []env.Type {env .NativeType }, "Go-server-request//read-body" )
636+ }
637+ },
638+ },
639+
640+ // Example:
641+ // ; Inside a handler: req .Headers?
642+ // ; Inside a handler: req .Headers? |print
643+ // Args:
644+ // * request: Native Go-server-request object from HTTP handler
645+ // Returns:
646+ // * dict containing all request headers
647+ "Go-server-request//Headers?" : {
648+ Argsn : 1 ,
649+ Doc : "Gets all HTTP request headers as a dictionary." ,
650+ Fn : func (ps * env.ProgramState , arg0 env.Object , arg1 env.Object , arg2 env.Object , arg3 env.Object , arg4 env.Object ) env.Object {
651+ switch req := arg0 .(type ) {
652+ case env.Native :
653+ headers := make (map [string ]any )
654+ for key , values := range req .Value .(* http.Request ).Header {
655+ if len (values ) == 0 {
656+ headers [key ] = ""
657+ } else if len (values ) == 1 {
658+ headers [key ] = values [0 ]
659+ } else {
660+ vals := make ([]env.Object , len (values ))
661+ for i , v := range values {
662+ vals [i ] = * env .NewString (v )
663+ }
664+ headers [key ] = * env .NewBlock (* env .NewTSeries (vals ))
665+ }
666+ }
667+ return * env .NewDict (headers )
668+ default :
669+ ps .FailureFlag = true
670+ return MakeArgError (ps , 1 , []env.Type {env .NativeType }, "Go-server-request//headers?" )
671+ }
672+ },
673+ },
674+
496675 // Example:
497676 // ; Inside a handler: url: req .Url?
498677 // ; equal { url .type? } 'native
0 commit comments