1YAWS_API(5)                        User API                        YAWS_API(5)
2
3
4

NAME

6       yaws_api - api available to yaws web server programmers
7

SYNOPSIS

9       yaws_api:Function(...)
10
11

DESCRIPTION

13       This  is  the  api available to yaws web server programmers. The Erlang
14       module yaws_api contains a wide variety of functions that can  be  used
15       inside yaws pages.
16
17
18       Each chunk of yaws code is executed while the yaws page is being deliv‐
19       ered from the server. We give a very simple example here  to  show  the
20       basic idea. Imagine the following HTML code:
21
22
23       <html>
24       <body>
25
26       <h1> Header 1</h1>
27
28       <erl>
29       out(Arg) ->
30           {html, "<p> Insert this text into the document"}.
31       </erl>
32
33       </body>
34       </html>
35
36
37
38
39
40       The  out(Arg)  function  is supplied one argument, an #arg{} structure.
41       We have the following relevant record definitions:
42
43
44
45       -record(arg, {
46                 clisock,        %% the socket leading to the peer client
47                 client_ip_port, %% {ClientIp, ClientPort} tuple
48                 headers,        %% headers
49                 req,            %% request
50                 clidata,        %% The client data (as a binary in POST requests)
51                 server_path,    %% The normalized server path
52                 querydata,      %% Was the URL on the form of ...?query (GET reqs)
53                 appmoddata,     %% the remainder of the path up to the query
54                 docroot,        %% where's the data
55                 fullpath,       %% full path to yaws file
56                 cont,                  %% Continuation for chunked multipart uploads
57                 state,          %% State for use by users of the out/1 callback
58                 pid,            %% pid of the yaws worker process
59                 opaque,         %% useful to pass static data
60                 appmod_prepath, %% path in front of: <appmod><appmoddata>
61                 pathinfo        %% Set to 'd/e' when calling c.yaws for the request
62                                 %% http://some.host/a/b/c.yaws/d/e
63                }).
64
65
66       The headers argument is also a record:
67
68       -record(headers, {
69                 connection,
70                 accept,
71                 host,
72                 if_modified_since,
73                 if_match,
74                 if_none_match,
75                 if_range,
76                 if_unmodified_since,
77                 range,
78                 referer,
79                 user_agent,
80                 accept_ranges,
81                 cookie = [],
82                 keep_alive,
83                 content_length,
84                 authorization,
85                 other = []   %% misc other headers
86                }).
87
88
89
90
91       it likes. We have the following functions to aid that generation.
92
93
94

API

96       ssi(DocRoot, ListOfFiles)
97              Server side include. Just include the files as is in  the  docu‐
98              ment. The files will not be parsed and searched for <erl> tags.
99
100
101
102       pre_ssi_files(DocRoot, ListOfFiles) ->
103              Server  side  include  of  pre indented code.  The data in Files
104              will be included but contained in a <pre> tag. The data will  be
105              htmlized.
106
107
108       pre_ssi_string(String)
109              Include htmlized content from String.
110
111
112
113       f(Fmt, Args)
114              The  equivalent  of  io_lib:format/2. This function is automati‐
115              cally -included in all erlang code which is a  part  of  a  yaws
116              page.
117
118
119       htmlize(Binary | List | Char)
120              Htmlize an IO list object.
121
122
123       setcookie(Name, Value, [Path, [ Expire, [Domain , [Secure]]]])
124              Sets a cookie to the browser.
125
126
127       find_cookie_val(Cookie, Header)
128              This function can be used to search for a cookie that was previ‐
129              ously set by setcookie/2-6. For example if we set  a  cookie  as
130              yaws_api:setcookie("sid",SomeRandomSid)  ,  then  on  subsequent
131              requests     from     the     browser     we      can      call:
132              find_cookie("sid",(Arg#arg.headers)#headers.cookie)
133
134              The  function  returns  [] if no cookie was found, otherwise the
135              actual cookie is returned as a string.
136
137
138
139       redirect(Url
140              This function generates a redirect  to  the  browser.   It  will
141              clear  any previously set headers. So to generate a redirect and
142              set a cookie, we need to set the cookie after  the  redirect  as
143              in:
144              out(Arg) ->
145                ... do some stuff
146
147                Ret = [{redirect, "http://www.somewhere.com"},
148                        setcookie("sid", Random)
149                      ].
150
151
152
153
154
155       redirect_self(Arg)
156              If  we  want  to issue a redirect to ourselves, this function is
157              useful.  It  returns   a   record   #redir_self{}   defined   in
158              yaws_api.hrl.  The  record contains fields to construct a URL to
159              ourselves.
160
161              -record(redir_self, {
162                        host,        %% string() - our own host
163                        scheme,      %% http | https
164                        scheme_str,  %% "https://"  | "http://"
165                        port,        %% integer()  - our own port
166                        port_str     %% "" | ":<int>" - the optional port part
167                                     %%                 to append to the url
168                       }).
169
170
171
172       get_line(String)
173              This function is convenient when getting \r\n terminated lines
174              from a stream of data. It returns:
175
176              {line, Line, Tail} or {lastline, Line, Tail}
177
178              The function handles multilines as defined in e.g. SMTP or HTTP
179
180
181       mime_type(FileName)
182              Returns the mime type as defined by the extension of FileName
183
184
185       stream_chunk_deliver(YawsPid, Data)
186              When a yaws function needs to deliver chunks of data which it gets
187              from a process. The other process can call this function to deliver
188              these chunks. It requires the out/1 function to return the
189              value {streamcontent, MimeType, FirstChunk} to work.
190              YawsPid is the process identifier of the yaws process delivering the original
191              The Pid must typically be passed (somehow) to the producer of the stream.
192
193
194       stream_chunk_deliver_blocking(YawsPid, Data)
195              A synchronous version of the above function. This synchronous version
196              must always be used when the producer of the stream is faster than the
197              consumer. This is usually the case since the client is the WWW browser.
198
199
200       stream_chunk_end(YawsPid)
201              When the process discussed above is done delivering data, it must call
202              this function to let the yaws content delivering process finish up
203              the HTTP transaction.
204
205
206       stream_process_deliver(Socket, IoList)
207              Yaws allows application processes to deliver data directly to the
208              client. The application tells yaws about such a process by returning
209              {streamcontent_from_pid, MimeType, Pid} from its out/1
210              function. In this case, Pid uses the
211              stream_process_deliver/2 function to deliver data to the
212              client. The application gets Socket from Arg#arg.clisock,
213              and IoList is the data to be sent to the client.
214
215
216       stream_process_deliver_chunk(Socket, IoList)
217              Same as above but delivers IoList using HTTP chunked transfer
218              format. IoList must have a size greater than zero. The
219              application process delivering the data will have had to have make
220              sure that the HTTP headers of the response indicate chunked transfer
221              mode, either by ensuring no Content-Length header is set or by
222              specifically setting the Transfer-Encoding header to chunked.
223
224
225       stream_process_deliver_final_chunk(Socket, IoList)
226              If the application process delivering data to the client uses chunked
227              transfer mode, it must call this to deliver the final chunk of the
228              transfer. This tells yaws to create a special final chunk in the
229              format required by the HTTP specification (RFC 2616). IoList may
230              be empty, but if its size is greater than zero, that data will be
231              sent as a separate chunk before the final chunk.
232
233
234       stream_process_end(Socket, YawsPid)
235              Application processes delivering data directly to clients must call
236              this function to inform yaws that they've finished using
237              Socket. The YawsPid argument will have been passed to the
238              process earlier when yaws sent it a message telling it to proceed with
239              data delivery. Yaws expects Socket to be open.
240
241
242       stream_process_end(closed, YawsPid)
243              Same as the previous function but the application calls this if it
244              closes the client socket as part of its data delivery process. This
245              allows yaws to continue without assuming the socket is still open and
246              encountering errors due to that assumption. The YawsPid argument
247              will have been passed to the application process earlier when yaws
248              sent it a message telling it to proceed with data delivery.
249
250
251       parse_query(Arg)
252              This function will parse the query part of the URL.
253              It will return a {Key, Value} list of the items supplied in the query
254              part of the URL.
255
256
257       queryvar(Arg, VarName)
258              This function is automatically included from yaws_api in all
259               .yaws pages. It is used to search for a variable in the
260              querypart of the url. Returns {ok, Val} or undefined.
261              If a variable is defined multiple times, the function may also
262              return {Val1, ....}.
263
264
265
266       parse_post(Arg)
267              This function will parse the POST data as supplied from the browser.
268              It will return a {Key, Value} list of the items set by the browser.
269
270
271       postvar(Arg, VarName)
272              This function is automatically included from yaws_api in all
273               .yaws pages. It is used to search for a variable in the
274              POSTed data from the client. Returns {ok, Val} or undefined.
275              If a variable is defined multiple times, the function may also
276              return {Val1, ....}.
277
278
279       getvar(Arg, VarName)
280              This function  looks at the HTTP request method from the
281              client and invokes postvar/2 if it is a POST from the client
282              and queryvar/2 if it is a GET request from the client.
283
284
285
286       parse_multipart_post(Arg)
287
288              If the browser has set the Content-Type header to the value
289              "multipart/form-data", which is the case when the browser
290              wants to upload a file to the server the following happens:
291
292
293              If the function returns {result, Res} no more data
294              will come from the browser.
295
296              If the function returns {cont, Cont, Res} the browser
297              will supply more data. (The file was to big to come in one read)
298
299              This indicates that there is more data to come and the out/1 function
300              should return {get_more, Cont, User_state} where User_state might
301              usefully be a File Descriptor.
302
303
304              The Res value is a list of either:
305              {header, Header} | {part_body, Binary} | {body, Binary}
306
307
308              Example usage could be:
309               <erl>
310
311               out(A) ->
312                      case yaws_api:parse_multipart_post(A) of
313                           {cont, Cont, Res} ->
314                                  St = handle_res(A, Res),
315                                  {get_more, Cont, St};
316                           {result, Res} ->
317                                  handle_res(A, Res),
318                                  {html, f("<pre>Done </pre>",[])}
319                      end.
320
321               handle_res(A, [{head, Name}|T]) ->
322                    io:format("head:~p~n",[Name]),
323                    handle_res(A, T);
324               handle_res(A, [{part_body, Data}|T]) ->
325                    io:format("part_body:~p~n",[Data]),
326                    handle_res(A, T);
327               handle_res(A, [{body, Data}|T]) ->
328                    io:format("body:~p~n",[Data]),
329                    handle_res(A, T);
330               handle_res(A, []) ->
331                    io:format("End_res~n").
332
333               </erl>
334
335
336
337
338
339       new_cookie_session(Opaque)
340              Create a new cookie based session, the yaws system will set  the
341              cookie.  The  new  random generated cookie is returned from this
342              function. The Opaque argument will typically contain  user  data
343              such as user name and password
344
345
346       new_cookie_session(Opaque, TTL)
347              As  above,  but allows to set a session specific time-out value,
348              overriding the system specified time-out value.
349
350
351       new_cookie_session(Opaque, TTL, CleanupPid)
352              As above, but also sends a  message  {yaws_session_end,  Reason,
353              Cookie,  Opaque}  to  the provided CleanuPid where Reason can be
354              either of timeout or normal. The Cookie is the  HTTP  cookie  as
355              returned  by  new_session()  and the Opaque is the user provided
356              Opaque parameter to new_session().  The purpose of  the  feature
357              is to cleanup resources assigned to the session.
358
359
360
361       cookieval_to_opaque(CookieVal)
362
363
364       print_cookie_sessions()
365
366
367
368       replace_cookie_session(Cookie, NewOpaque)
369
370
371       delete_cookie_session(Cookie)
372
373
374
375       setconf(Gconf, Groups)
376              This function is intended for embedded mode in yaws. It makes it
377              possible to load a yaws configuration from another  data  source
378              than  /etc/yaws.conf,  such  as  a database.  If yaws is started
379              with the environment {embedded, true}, yaws will start  with  an
380              empty  default configuration, and wait for some other program to
381              execute a setconf/2 The Gconf is a #gconf{} record and the Group
382              variable  is  a  list of lists of #sconf{} records. Each sublist
383              must contain #sconf{}  records  with  the  same  IP/Port  listen
384              address.   To  create a suitable initial #gconf{} record see the
385              code   in   yaws_config:make_default_gconf/2.   Especially   the
386              yaws_dir parameter is important to get right.
387
388
389
390       url_decode(Str)
391              Decode  url-encoded  string.  A  URL  encoded string is a string
392              where all alfa numeric characters and the the  character  _  are
393              preserved  and  all other characters are encode as "%XY" where X
394              and Y are the hex values of the least respective  most  signifi‐
395              cant 4 bits in the 8 bit character.
396
397
398       url_encode(Str)
399              Url-encodes  a  string.  All  URLs in HTML documents must be URL
400              encoded.
401
402
403
404       reformat_header(H)
405              Returns a list of reformatted header  values  from  a  #header{}
406              record. The return list is suitable for retransmit.
407
408
409       request_url(ARG)
410              Return  the  url  as  requested by the client. Return value is a
411              #url{} record as defined in yaws_api.hrl
412
413
414
415       parse_url(Str)
416              Parse URL in a string, returns a #url record
417
418
419       format_url(UrlRecord)
420              Takes a #url record a formats the Url as a string
421
422
423       call_cgi(Arg, Scriptfilename)
424              Calls an executable CGI script, given by its full path.  Used to
425              make  `.yaws'  wrappers for CGI programs.  This function usually
426              returns streamcontent.
427
428
429       call_cgi(Arg, Exefilename, Scriptfilename)
430              Like before, but calls Exefilename to handle  the  script.   The
431              file  name  of  the script is handed to the executable via a CGI
432              meta variable.
433
434
435       call_fcgi_responder(Arg)
436              Calls a FastCGI responder.  The address and port of the  FastCGI
437              application  server are taken from the server configuration (see
438              yaws.conf).  Used to make `.yaws' wrappers for  FastCGI  respon‐
439              ders.  Returns the same return values as out/1 (see below).
440
441
442       call_fcgi_responder(Arg, Options)
443              Same  as  above,  but  Options  overrides  the defaults from the
444              server configuration:
445
446
447              Options = [Option]
448              Option -- one of the following:
449
450
451              {app_server_host, string() | ip_address()} The hostname  or  the
452              IP address of the FastCGI application server.
453
454              {app_server_port,  0..65535}  The TCP port number of the FastCGI
455              application server.
456
457              {path_info,   string()}    Override    default    pathinfo    in
458              Arg#arg.pathinfo.
459
460              {extra_env,    ExtraEnv}    Override    default    pathinfo   in
461              Arg#arg.pathinfo.
462
463
464              ExtraEnv = [Var]
465              Var = {Name, Value}
466              Name = string()
467              Value = string()
468
469
470              {trace_protocol, boolean()} Enable or disable tracing of FastCGI
471              protocol messages as info log messages.
472
473              {log_app_error, boolean()} Enable or disable logging of applica‐
474              tion error messages: output to stderr and non-zero exit value.
475
476
477       call_fcgi_authorizer(Arg) -> {allowed, Out} | {denied, Out}
478              Calls a FastCGI authorizer.  The address and port of the FastCGI
479              application  server are taken from the server configuration (see
480              yaws.conf).  Used to make `.yaws' wrappers for FastCGI authoriz‐
481              ers.  Variables contains the values of the variables returned by
482              the FastCGI application server in the "Variable-XXX: YYY"  head‐
483              ers.
484
485              If access is denied, Out contains the complete response returned
486              by the FastCGI application server. This  response  is  typically
487              returned as-is to the HTTP client.
488
489              If  access is allowed, Out contains the response returned by the
490              FastCGI application server minus the body (i.e. minus  the  con‐
491              tent)  which  should  be  ignored per the FastCGI specification.
492              This response is typically not returned to the HTTP client.  The
493              calling application module may wish to inspect the response, for
494              example  by  extracting  variables  (see  fcgi_extract_variables
495              below)  or  by  inspecting  the  headers returned by the FastCGI
496              application server.
497
498
499              Out -- See return values for out/1 below
500
501
502
503       call_fcgi_authorizer(Arg, Options) -> {allowed, Out} | {denied, Out}
504              Same as above, but  Options  overrides  the  defaults  from  the
505              server  configuration.  See  call_fcgi_responder/2  above  for a
506              description of Options.
507
508
509       fcgi_extract_variables(Out) -> [{Name, Value}]
510              Extracts the environment variables  from  a  FastCGI  authorizer
511              response  by  looking  for  headers  of the form "Variable-Name:
512              Value".
513
514
515              Name = string() -- The name of the variable (the "Variable-" prefix
516              has already been removed).
517              Value = string() -- The value of the variable.
518
519
520
521       dir_listing(Arg)
522              Perform a directory listing. Can be used in special  directories
523              when  we  don't  want  to  turn  on  dir listings for the entire
524              server.  Always returns ok.
525
526

RETURN VALUES from out/1

528       The out/1 function can return different values to control the  behavior
529       of the server.
530
531
532       {html, DeepList}
533              This  assumes  that  DeepList  is formatted HTML code.  The code
534              will be inserted in the page.
535
536
537       {ehtml, Term}
538              This will transform the erlang term Term into a stream  of  HTML
539              content. The basic syntax of Term is
540
541
542              EHTML = [EHTML] | {Tag, Attrs, Body} | {Tag, Attrs} | {Tag} |
543                      binary() | character()
544              Tag      = atom()
545              Attrs = [{Key, Value}]  or {EventTag, {jscall, FunName, [Args]}}
546              Key      = atom()
547              Value = string()
548              Body  = EHTML
549
550
551
552              For example, {p, [], "Howdy"} expands into "<p>Howdy</p> and
553
554
555              {form, [{action, "a.yaws"}],
556                 {input, [{type,text}]}}
557
558
559
560              expands into
561
562
563              <form action="a.yaws"
564                <input type="text">
565              </form>
566
567
568              It  may  be more convenient to generate erlang tuples than plain
569              html code.
570
571
572       {content, MimeType, Content}
573              This function will make the web server generate  different  con‐
574              tent than HTML. This return value is only allowed in a yaws file
575              which has only one <erl> </erl> part and no html parts at all.
576
577
578
579       {streamcontent, MimeType, FirstChunk}
580              This return value plays the same  role  as  the  content  return
581              value above.
582
583              However it makes it possible to stream data to the client if the
584              yaws code doesn't have access to all the data in one go.  (Typi‐
585              cally  if  a file is very large or if data arrives from back end
586              servers on the network.
587
588
589       {streamcontent_with_timeout, MimeType, FirstChunk, Timeout}
590              Similar to above, but with  an  explicit  timeout.  The  deafult
591              timeout is 30 secs. I.e if the application fails to deliver data
592              to the Yaws process, the streaming will stop. This is often  not
593              the desired behaviour in Comet/Ajax applications.  It's possible
594              to provide 'infinity' as timeout.
595
596
597       {header, H}
598              Accumulates a HTTP header. The trailing CRNL which  is  supposed
599              to  end  all  HTTP headers must NOT be added. It is added by the
600              server.  The following list of headers are given special  treat‐
601              ment.
602
603              {connection, What}
604
605              This  sets  the  connection header. If What is the special value
606              "close", the connection will be closed once  the  yaws  page  is
607              delivered to the client.
608
609              {location, Url}
610
611              Sets  the  Location:  header.  This header is typically combined
612              with the {status, 302} return value.
613
614              {cache_control, What}
615
616              Sets the Cache-Control: header.
617
618              {set_cookie, Cookie}
619
620              Prepends a a Set-Cookie: header to the list  of  previously  set
621              Set-Cookie: headers.
622
623              {content_type, MimeType}
624
625              Sets the Content-Type header.
626
627              {content_length, Len}
628
629              Normally  yaws  will  ship  Yaws  pages using Transfer-Encoding:
630              chunked. This is because we generally can't know how long a yaws
631              page  will  be.  If  we for some reason want to force a Content-
632              Length: header (and we actually do know the length of  the  con‐
633              tent, we can force yaws to not ship the page chunked.
634
635
636              All  other  headers  must be added using the normal HTTP syntax.
637              Example:
638
639              {header, "My-X-Header: gadong"}
640
641
642
643
644
645       {allheaders, HeaderList}
646              Will clear all previously accumulated headers and replace them.
647
648
649
650       {status, Code}
651              Will set another HTTP status code than 200.
652
653
654
655       break  Will stop processing of any consecutive chunks of  erl  or  html
656              code in the yaws file.
657
658
659       ok     Do nothing.
660
661
662
663       {redirect, Url}
664              Erase  all  previous  headers  and  accumulate a single Location
665              header. Set the status code.
666
667
668       {redirect_local, Path}
669              Does a redirect to the same Scheme://Host:Port/Path as  we  cur‐
670              rently are executing in.
671
672
673       {get_more, Cont, State}
674              When  we  are receiving large POSTs we can return this value and
675              be invoked again when more Data arrives.
676
677
678
679       {page, Page}
680              Make Yaws return a different page than the one being requested.
681
682
683
684       {page, {Options, Page}}
685              Like the  above,  but  supplying  an  additional  deep  list  of
686              options.   For  now, the only type of option is {header, H} with
687              the effect of accumulating the HTTP header H for page Page.
688
689
690
691       {ssi, File, Delimiter, Bindings}
692              Server side include File and  macro  expansion  in  File.   Each
693              occurrence  of  a string, say "xyz", inside File which is inside
694              Delimiters is replaced with the corresponding value in Bindings.
695
696              Example: Delimiter = %%
697
698              File contains the string .... %%xyz%%  .....
699
700              Bindings contain the tuple {"xyz", "Dingbat"}
701
702              The occurrence of %%xyz%% in File will be replaced  with  "Ding‐
703              bat" in the Server side included output.
704
705              The  {ssi,  File,  Delimiter, Bindings} statement can also occur
706              inside a deep ehtml structure.
707
708
709
710       {bindings, [{Key1, Value2}, {Key2, Value2} .....]}
711              Establish variable bindings that can be used in the page.
712
713              All bindings can then be used in the rest of yaws code (in  HTML
714              source and within erl tags).  In HTML source %%Key%% is expanded
715              to Value and within erl tags yaws_api:binding(Key) can  be  used
716              to extract Value and yaws_api:binding_exists(Key) can be used to
717              check for the existence of a binding.
718
719
720       {yssi, YawsFile}
721              Include a yaws file. Compile it and expand as if it had  occured
722              inline.
723
724
725       [ListOfValues]
726              It is possible to return a deep list of the above defined return
727              values.  Any occurrence of stream_content, get_more or  page  in
728              this list is legal only if it is the last position of the list.
729
730
731
732
733

AUTHOR

735       Written by Claes Wikstrom
736

SEE ALSO

738       yaws.conf(5) erl(1)
739
740
741
742
743                                                                   YAWS_API(5)
Impressum