1YAWS_API(5) User API YAWS_API(5)
2
3
4
6 yaws_api - api available to yaws web server programmers
7
9 yaws_api:Function(...)
10
11
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
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
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
735 Written by Claes Wikstrom
736
738 yaws.conf(5) erl(1)
739
740
741
742
743 YAWS_API(5)