$Web Form Done: Difference between revisions

From m204wiki
Jump to navigation Jump to search
 
(24 intermediate revisions by 4 users not shown)
Line 1: Line 1:
{{DISPLAYTITLE:$Web_Form_Done}}
{{DISPLAYTITLE:$Web_Form_Done}}
<span class="pageSubtitle"><section begin="desc" />Send Web Response for a Form<section end="desc" /></span>
<span class="pageSubtitle">Send Web Response for a Form</span>






$Web_Form_Done sends the current output data to the browser, or it redirects the browser to do a GET on the current URL, and sends the current output data to the browser when the GET request is received. $Web_Form_Done might then also wait for the POST of the form sent to the browser.
<var>$Web_Form_Done</var> sends the current output data to the browser, or it redirects the browser to do a GET on the current URL, and sends the current output data to the browser when the GET request is received. <var>$Web_Form_Done</var> might then also wait for the POST of the form sent to the browser.
$Web_Form_Done is [[Calling_Sirius_Mods_$functions|callable]], takes five arguments, and returns a number. A return of 0 indicates success; all other errors cause request cancellation.
 
<var>$Web_Form_Done</var> is [[Calling_Sirius_Mods_$functions|callable]], takes five arguments, and returns a number. A return of 0 indicates success; all other errors cause request cancellation.


==Syntax==
==Syntax==
<p class="syntax"><section begin="syntax" /> %RC = $Web_Form_Done(redir_timeout, post_timeout, options, -
<p class="syntax"><span class="term">%rc</span> = <span class="literal">$Web_Form_Done</span>([<span class="term"> redir_timeout</span>], [<span class="term">post_timeout</span>], [<span class="term">options</span>], <span class="term">check_field</span>, <span class="term">check_val</span>)
check_field, check_val)
</p>
<section end="syntax" /></p>


===Syntax terms===
===Syntax terms===
<table class="syntaxTable">
<table class="syntaxTable">
<tr><th>redir_timeout</th>
<tr><th>redir_timeout</th>
<td>The amount of time to wait for the GET resulting from the redirect that $Web_Form_Done might send to the browser. This parameter is optional; it may have the following values:
<td>The amount of time to wait for the GET resulting from the redirect that <var>$Web_Form_Done</var> might send to the browser. This parameter is optional; it may have the following values:
<ul>
<ul>
<li>A positive number, to indicate the number of seconds to wait.  
<li>A positive number, to indicate the number of seconds to wait.  
Line 22: Line 22:
</ul>
</ul>
For additional comments, see [[#Setting timeout values|"Setting timeout values"]]. </td></tr>
For additional comments, see [[#Setting timeout values|"Setting timeout values"]]. </td></tr>
<tr><th>post_timeout</th>
<tr><th>post_timeout</th>
<td>The amount of time to wait for the POST of one of the forms or of the only form on the page sent by $Web_Form_Done. This parameter is optional; it may have the following values:
<td>The amount of time to wait for the POST of one of the forms or of the only form on the page sent by <var>$Web_Form_Done</var>. This parameter is optional; it may have the following values:
<ul>
<ul>
<li>A positive number, to indicate the number of seconds to wait.  
<li>A positive number, to indicate the number of seconds to wait.  
<li>-1, the default, to indicate that no wait for the POST is to be done.  
<li>-1, the default, to indicate that no wait for the POST is to be done.  
Line 37: Line 37:
<table class="syntaxTable">
<table class="syntaxTable">
<tr><th><var>FLUSH</var></th>
<tr><th><var>FLUSH</var></th>
<td>When a POST is received, flush the page that was sent. This eliminates the need to do a $Web_Flush before starting a new response page.</td></tr>
<td>When a POST is received, flush the page that was sent. This eliminates the need to do a <var>$Web_Flush</var> before starting a new response page.</td></tr>


<tr><th><var>NOFLUSH</var></th>
<tr><th><var>NOFLUSH</var></th>
<td>When a POST is received, do not flush the page that was sent. This makes it possible to re-send the current page by simply doing a <var>$Web_Done</var> or $Web_Form_Done. This is likely to be appropriate only if the application determines that a POST was from a stale copy of the page, though this is probably more easily handled by using a check form field. This is the default.</td></tr>
<td>When a POST is received, do not flush the page that was sent. This makes it possible to re-send the current page by simply doing a <var>$Web_Done</var> or <var>$Web_Form_Done</var>. This is likely to be appropriate only if the application determines that a POST was from a stale copy of the page, though this is probably more easily handled by using a check form field. This is the default.</td></tr>


<tr><th><var>GET</var></th>
<tr><th><var>GET</var></th>
Line 55: Line 55:
<p>
<p>
For additional comments, see [[#Using check fields|"Using check fields"]]. </p> </td></tr>
For additional comments, see [[#Using check fields|"Using check fields"]]. </p> </td></tr>
<tr><th>check_val</th>
<tr><th>check_val</th>
<td>The value to be compared against the value of the field specified by the fourth parameter in a POST. If the value does not match, the current page is resent, because the POST is probably from a stale copy of the form, probably reached via a ''Backpage''.  
<td>The value to be compared against the value of the field specified by the fourth parameter in a POST. If the value does not match, the current page is resent, because the POST is probably from a stale copy of the form, probably reached via a ''Backpage''.  
Line 64: Line 65:


==Usage notes==
==Usage notes==
$Web_Form_Done serves two basic purposes:
<var>$Web_Form_Done</var> serves two basic purposes:
<ul>
<ul>


Line 75: Line 76:
<li>It eliminates a separate URL in the browser cache for each POST of a form that results in the form being redisplayed with an error message.  
<li>It eliminates a separate URL in the browser cache for each POST of a form that results in the form being redisplayed with an error message.  


It is highly recommended that, whenever such a form redisplay is to be done, $Web_Form_Done be used with a 0 or positive first argument parameter rather than $Web_Done.
It is highly recommended that, whenever such a form redisplay is to be done, <var>$Web_Form_Done</var> be used with a 0 or positive first argument parameter rather than <var>$Web_Done</var>.
</ul>
</ul>


<li>To make possible persistent or conversational web applications.  
<li>To make possible persistent or conversational web applications.  


When 0 or a positive value is used for the second parameter on a $Web_Form_Done, the $WEB_FORM_DONE waits for the user to fill in the form and POST it. When $Web_Form_Done returns, the result of the POST can be examined with all context (%variables, images, found sets, lists, $lists and so on) preserved.  
When 0 or a positive value is used for the second parameter on a <var>$Web_Form_Done</var>, the <var>$Web_Form_Done</var> waits for the user to fill in the form and POST it. When <var>$Web_Form_Done</var> returns, the result of the POST can be examined with all context (%variables, images, found sets, lists, $lists and so on) preserved.  


While such a persistent or conversational web application is not a "true" web application because true web applications are completely stateless, they can still be quite useable. For example, it might be much easier to convert an existing conversational 3270 application into a conversational web application rather than into a stateless one.
While such a persistent or conversational web application is not a "true" web application because true web applications are completely stateless, they can still be quite useable. For example, it might be much easier to convert an existing conversational 3270 application into a conversational web application rather than into a stateless one.
</ul>
</ul>


The subsections that follow discuss further aspects of persistent sessions and how to set and work with $Web_Form_Done.  
The subsections that follow discuss further aspects of persistent sessions and how to set and work with <var>$Web_Form_Done</var>.  


===Managing URLs in persistent sessions===
===Managing URLs in persistent sessions===
The first execution of a persistent $WEB_FORM_DONE, that is, a $Web_Form_Done that waits for a POST, establishes the URL of the request that contains the function as the "base" URL for the persistent session.  
The first execution of a persistent <var>$Web_Form_Done</var>, that is, a <var>$Web_Form_Done</var> that waits for a POST, establishes the URL of the request that contains the function as the "base" URL for the persistent session.  


It is the programmer's responsibility to ensure that the action URL on the <form> tag matches the base URL for a persistent $Web_Form_Done (as discussed later below, Version 6.4 of ''[[Sirius Mods]]'' allows extensions to the base URL to also be considered a match). Similarly, it is the programmer's responsibility to ensure that method="POST" is used in the <form> tag. If either of these is neglected, $Web_Form_Done will never notice the POST of the form and will eventually time out.  
It is the programmer's responsibility to ensure that the action URL on the <code><form></code> tag matches the base URL for a persistent <var>$Web_Form_Done</var> (as discussed later below, Version 6.4 of ''[[Sirius Mods]]'' allows extensions to the base URL to also be considered a match). Similarly, it is the programmer's responsibility to ensure that method="POST" is used in the <code><form></code> tag. If either of these is neglected, <var>$Web_Form_Done</var> will never notice the POST of the form and will eventually time out.  


$Web_Form_Action is provided to facilitate correct setting of the action attribute of the <form> tag for persistent applications. Outside of truncation issues, $Web_Form_Action is guaranteed to return the exact URL for which a $Web_Form_Done with a non-negative POST wait time will be waiting.  
<var>[[$Web_Form_Action]]</var> is provided to facilitate correct setting of the action attribute of the <code><form></code> tag for persistent applications. Outside of truncation issues, <var>$Web_Form_Action</var> is guaranteed to return the exact URL for which a <var>$Web_Form_Done</var> with a non-negative POST wait time will be waiting.  


The following example illustrates the use of $Web_Form_Action with $Web_Form_Done. For additional details, see [[$Web_Form_Action]] and [[$Web_Form_Action_Len]].
The following example illustrates the use of <var>$Web_Form_Action</var> with <var>$Web_Form_Done</var>. For additional details, see <var>[[$Web_Form_Action]]</var> and <var>[[$Web_Form_Action_Len]]</var>.
<p class="code"> HTML
<p class="code">HTML
<form method="POST" -
<form method="POST" -
action="{$Web_Form_Action}">
action="{<var>$Web_Form_Action</var>.">
. . . . rest of form
  . . . rest of form
</form>
</form>
</body>
</body>
</html>
</html>
END HTML
END HTML
   
   
* Send the form and wait for the POST
&#42; Send the form and wait for the POST
   
   
%RC = $Web_Form_Done(0, 0)
%rc = $Web_Form_Done(0, 0)
</p>
</p>




As mentioned above, $Web_Form_Done has additional flexibility as of Version 6.4 of ''[[Sirius Mods]]'': Once the first $Web_Form_Done establishes the base URL, any browser request with a URL whose beginning matches this base URL (assuming user ID and other basic criteria also match) will be considered a response to the $Web_Form_Done. This allows parameters to be added to a base URL in a persistent session, and it allows hypertext links to continue a persistent session on one of its pages.  
As mentioned above, <var>$Web_Form_Done</var> has additional flexibility: Once the first <var>$Web_Form_Done</var> establishes the base URL, any browser request with a URL whose beginning matches this base URL (assuming user ID and other basic criteria also match) will be considered a response to the <var>$Web_Form_Done</var>. This allows parameters to be added to a base URL in a persistent session, and it allows hypertext links to continue a persistent session on one of its pages.  


For example, if a persistent session is created by URL ''/cust/update?crn=54321'', a page generated for this session can have a link like:
For example, if a persistent session is created by URL <code>/cust/update?crn=54321</code>, a page generated for this session can have a link like:
<p class="code"> <a href="/cust/update?crn=54321&view=history">History</a>
<p class="code"><a href="/cust/update?crn=54321&view=history">History</a>
</p>
</p>


When the user clicks on this link, the <var>$Web_Form_Done</var> for the session returns. The request can then examine the URL sent from the browser using <var>[[$Web_IsIndex_Parm]]</var> or <var>[[$Web_Parm]]</var>, can determine that the URL parameter <code>view</code> is set to <code>history</code>, and can take appropriate action.


When the user clicks on this link, the $Web_Form_Done for the session returns. The request can then examine the URL sent from the browser using $Web_IsIndex_Parm or $WEB_PARM, can determine that the URL parameter ''view'' is set to "history", and can take appropriate action.
Many releases of Netscape Navigator and Netscape Communicator have the following problem: when a POST is redirected to a GET for a URL that exactly matches the POST action URL, the browser decides it is in a redirect loop and refuses to do the GET. If you want to use the redirect aspect of <var>$Web_Form_Done</var> with such versions of Netscape Navigator or Netscape Communicator, they can be "tricked" into working by adding an octothorpe (#) character at the end of the action URL, as in:
 
<p class="code">HTML
Many releases of Netscape Navigator and Netscape Communicator have the following problem: when a POST is redirected to a GET for a URL that exactly matches the POST action URL, the browser decides it is in a redirect loop and refuses to do the GET. If you want to use the redirect aspect of $Web_Form_Done with such versions of Netscape Navigator or Netscape Communicator, they can be "tricked" into working by adding an octothorpe (#) character at the end of the action URL, as in:
<form method="POST" -
<p class="code"> HTML
action="{<var>$Web_Form_Action</var>.#">
<form method="POST" -
  . . . rest of form
action="{$Web_Form_Action}#">
</form>
  . . . . rest of form
</body>
</form>
</html>
</body>
END HTML
</html>
END HTML
   
   
* Send the form
&#42; Send the form
   
   
%RC = $Web_Form_Done
%rc = $Web_Form_Done
</p>
</p>
This doesn't seem to cause any problems with other browsers, so it is a safe tactic if you are unsure about whether any end users will be using a version of Netscape with this bug.  
This doesn't seem to cause any problems with other browsers, so it is a safe tactic if you are unsure about whether any end users will be using a version of Netscape with this bug.


===Setting timeout values===  
===Setting timeout values===  
Line 142: Line 142:
Unfortunately, persistent web applications have no way of knowing if or when a user has navigated away from the application by clicking on a hypertext link on one of the application pages, by backpaging through her browser cache, by selecting a browser bookmark, or by explicitly typing in a URL. There is also no way to determine when a user exits the browser or simply shuts down the workstation. For these reasons, it is probably a good idea to make the wait timeout of the POST somewhat conservative. It is also probably a good idea to keep the default setting of 1 for the port definition parameter MAXIPSES. This limits the number for persistent legacy sessions per user to one.  
Unfortunately, persistent web applications have no way of knowing if or when a user has navigated away from the application by clicking on a hypertext link on one of the application pages, by backpaging through her browser cache, by selecting a browser bookmark, or by explicitly typing in a URL. There is also no way to determine when a user exits the browser or simply shuts down the workstation. For these reasons, it is probably a good idea to make the wait timeout of the POST somewhat conservative. It is also probably a good idea to keep the default setting of 1 for the port definition parameter MAXIPSES. This limits the number for persistent legacy sessions per user to one.  


In addition, while it is possible to specify a separate POST timeout on each $WEB_FORM_DONE, it is probably better to specify a value of 0 and to use the FORMPOSTWAIT default of 900 or the value specified on the port definition or ON rule. This ensures a consistent session timeout value within an application or web server, and it makes it easy to change the session timeout as needed.  
In addition, while it is possible to specify a separate POST timeout on each <var>$Web_Form_Done</var>, it is probably better to specify a value of 0 and to use the FORMPOSTWAIT default of 900 or the value specified on the port definition or ON rule. This ensures a consistent session timeout value within an application or web server, and it makes it easy to change the session timeout as needed.


===Identifying the request user===  
===Identifying the request user===  
$Web_Form_Done depends not only on URLs being consistent between GET and POST requests, they depend on requests by different users being distinguishable. $Web_Form_Done will use every bit of data at its disposal to distinguish requests and so prevent one user from seeing another user's data. Among these bits of data are:
<var>$Web_Form_Done</var> depends not only on URLs being consistent between GET and POST requests, they depend on requests by different users being distinguishable. <var>$Web_Form_Done</var> will use every bit of data at its disposal to distinguish requests and so prevent one user from seeing another user's data. Among these bits of data are:
<ul>
<ul>


Line 156: Line 156:


===Using check fields===
===Using check fields===
When using $Web_Form_Done with a non-negative POST wait time, that is when using a persistent session, the URL for the persistent session might produce several different forms, all of which get posted to the same URL. This is not a problem when things are working well and users are cooperative. However, if a user were to backpage to a previous form in the persistent session and then POST it, $Web_Form_Done would have no way of knowing this has happened. It would return to the application with one form posted while the application expected another. This could cause serious application problems if the application is not written to deal with the situation, and in any case, an application coder would prefer not to have to worry about this.  
When using <var>$Web_Form_Done</var> with a non-negative POST wait time, that is when using a persistent session, the URL for the persistent session might produce several different forms, all of which get posted to the same URL. This is not a problem when things are working well and users are cooperative. However, if a user were to backpage to a previous form in the persistent session and then POST it, <var>$Web_Form_Done</var> would have no way of knowing this has happened. It would return to the application with one form posted while the application expected another. This could cause serious application problems if the application is not written to deal with the situation, and in any case, an application coder would prefer not to have to worry about this.  


To solve this forms problem, ''[[Janus Web Server]]'' provides the check field and check value parameters on the $Web_Form_Done call, which can be used as follows:
To solve this forms problem, ''Janus Web Server'' provides the check field and check value parameters on the <var>$Web_Form_Done</var> call, which can be used as follows:
<ol>
<ol>


<li>Each form sent to the browser as part of a persistent session must have a hidden field that contains a value unique to that incarnation of the form, typically a time stamp.  
<li>Each form sent to the browser as part of a persistent session must have a hidden field that contains a value unique to that incarnation of the form, typically a time stamp.  
<li>The name of the hidden field and its value are passed to $WEB_FORM_DONE, which checks the value of the field when it receives a POST.  
<li>The name of the hidden field and its value are passed to <var>$Web_Form_Done</var>, which checks the value of the field when it receives a POST.  
<li>If the value of the field is not the same as that specified on the $Web_Form_Done call, ''[[Janus Web Server]]'' resends the current form on the URL. It assumes that the user has backpaged and POST'ed, so displaying the most recent page in the persistent session is the most logical action.
<li>If the value of the field is not the same as that specified on the <var>$Web_Form_Done</var> call, ''Janus Web Server'' resends the current form on the URL. It assumes that the user has backpaged and POST'ed, so displaying the most recent page in the persistent session is the most logical action.
</ol>
</ol>
The following code demonstrates the use of such a hidden check field:
The following code demonstrates the use of such a hidden check field:
<p class="code"> %TIMESTAMP = $Web_Date
<p class="code">%TIMESTAMP = $Web_Date
HTML
HTML
<form method="POST" -
<form method="POST" -
action="{$Web_Form_Action}">
action="{<var>$Web_Form_Action</var>.">
<input type="hidden" name="validate" -
<input type="hidden" name="validate" -
value="{%TIMESTAMP}">
value="{%TIMESTAMP}">
  . . . more form stuff
  . . . more form stuff
END HTML
END HTML
%RC = $Web_Form_Done(0, 0, , -
%rc = $Web_Form_Done(0, 0, , -
'validate', %TIMESTAMP)
'validate', %TIMESTAMP)
</p>
</p>




[[Category:Janus Web Server $functions|$Web_Form_Done]]
[[Category:Janus Web Server $functions|$Web_Form_Done]]

Latest revision as of 22:28, 5 June 2013

Send Web Response for a Form


$Web_Form_Done sends the current output data to the browser, or it redirects the browser to do a GET on the current URL, and sends the current output data to the browser when the GET request is received. $Web_Form_Done might then also wait for the POST of the form sent to the browser.

$Web_Form_Done is callable, takes five arguments, and returns a number. A return of 0 indicates success; all other errors cause request cancellation.

Syntax

%rc = $Web_Form_Done([ redir_timeout], [post_timeout], [options], check_field, check_val)

Syntax terms

redir_timeout The amount of time to wait for the GET resulting from the redirect that $Web_Form_Done might send to the browser. This parameter is optional; it may have the following values:
  • A positive number, to indicate the number of seconds to wait.
  • -1, to indicate that no redirect is to be done.
  • 0, the default, to indicate that the FORMREDIRWAIT default (typically 60), the value set in the port definition, or the value set in the ON rule associated with the current request is to be used.
For additional comments, see "Setting timeout values".
post_timeout The amount of time to wait for the POST of one of the forms or of the only form on the page sent by $Web_Form_Done. This parameter is optional; it may have the following values:
  • A positive number, to indicate the number of seconds to wait.
  • -1, the default, to indicate that no wait for the POST is to be done.
  • 0, to indicate that the FORMPOSTWAIT default (typically 900), the value set in the port definition, or the value set in the ON rule associated with the current request is to be used.
For additional comments, see "Setting timeout values".
options A blank-delimited set of options for specifying the port's response processing when a POST to the web server URL is expected. This parameter has two defaults: one for how to respond if a POST is received, and one for how to respond if a GET is received. The valid options are:
FLUSH When a POST is received, flush the page that was sent. This eliminates the need to do a $Web_Flush before starting a new response page.
NOFLUSH When a POST is received, do not flush the page that was sent. This makes it possible to re-send the current page by simply doing a $Web_Done or $Web_Form_Done. This is likely to be appropriate only if the application determines that a POST was from a stale copy of the page, though this is probably more easily handled by using a check form field. This is the default.
GET When a GET is received (most likely as the result of a Refresh or Reload), resend the current page. This is the default.
NOGET When a GET is received (most likely as the result of a Refresh or Reload), terminate the wait for the POST, and process the request as if a GET had been done for the URL for the first time.
check_field The name of the form field in a POST whose value will be compared against the value specified in the fifth parameter. If the value does not match, the current page is resent, because the POST is probably from a stale copy of the form, probably reached via a Backpage.

This parameter should almost certainly contain the name of a hidden form field on the form for which the POST is being waited.

For additional comments, see "Using check fields".

check_val The value to be compared against the value of the field specified by the fourth parameter in a POST. If the value does not match, the current page is resent, because the POST is probably from a stale copy of the form, probably reached via a Backpage.

This parameter should almost certainly contain the value of a hidden form field on the form for which the POST is being waited. It should be a value such as a timestamp that will be different on every form.

For additional comments, see "Using check fields".

Usage notes

$Web_Form_Done serves two basic purposes:

  • To eliminate pages that are returned as the result of a POST. This is accomplished by redirecting back to the current URL when a page is to be returned for a POST. Since a browser always converts a redirect to a GET, the result page ends up being a GET result. This is important because:
    • It eliminates browser warning messages about re-posts on Backpage operations.
    • It eliminates a separate URL in the browser cache for each POST of a form that results in the form being redisplayed with an error message. It is highly recommended that, whenever such a form redisplay is to be done, $Web_Form_Done be used with a 0 or positive first argument parameter rather than $Web_Done.
  • To make possible persistent or conversational web applications. When 0 or a positive value is used for the second parameter on a $Web_Form_Done, the $Web_Form_Done waits for the user to fill in the form and POST it. When $Web_Form_Done returns, the result of the POST can be examined with all context (%variables, images, found sets, lists, $lists and so on) preserved. While such a persistent or conversational web application is not a "true" web application because true web applications are completely stateless, they can still be quite useable. For example, it might be much easier to convert an existing conversational 3270 application into a conversational web application rather than into a stateless one.

The subsections that follow discuss further aspects of persistent sessions and how to set and work with $Web_Form_Done.

Managing URLs in persistent sessions

The first execution of a persistent $Web_Form_Done, that is, a $Web_Form_Done that waits for a POST, establishes the URL of the request that contains the function as the "base" URL for the persistent session.

It is the programmer's responsibility to ensure that the action URL on the <form> tag matches the base URL for a persistent $Web_Form_Done (as discussed later below, Version 6.4 of Sirius Mods allows extensions to the base URL to also be considered a match). Similarly, it is the programmer's responsibility to ensure that method="POST" is used in the <form> tag. If either of these is neglected, $Web_Form_Done will never notice the POST of the form and will eventually time out.

$Web_Form_Action is provided to facilitate correct setting of the action attribute of the <form> tag for persistent applications. Outside of truncation issues, $Web_Form_Action is guaranteed to return the exact URL for which a $Web_Form_Done with a non-negative POST wait time will be waiting.

The following example illustrates the use of $Web_Form_Action with $Web_Form_Done. For additional details, see $Web_Form_Action and $Web_Form_Action_Len.

HTML <form method="POST" - action="{$Web_Form_Action."> . . . rest of form </form> </body> </html> END HTML * Send the form and wait for the POST %rc = $Web_Form_Done(0, 0)


As mentioned above, $Web_Form_Done has additional flexibility: Once the first $Web_Form_Done establishes the base URL, any browser request with a URL whose beginning matches this base URL (assuming user ID and other basic criteria also match) will be considered a response to the $Web_Form_Done. This allows parameters to be added to a base URL in a persistent session, and it allows hypertext links to continue a persistent session on one of its pages.

For example, if a persistent session is created by URL /cust/update?crn=54321, a page generated for this session can have a link like:

<a href="/cust/update?crn=54321&view=history">History</a>

When the user clicks on this link, the $Web_Form_Done for the session returns. The request can then examine the URL sent from the browser using $Web_IsIndex_Parm or $Web_Parm, can determine that the URL parameter view is set to history, and can take appropriate action.

Many releases of Netscape Navigator and Netscape Communicator have the following problem: when a POST is redirected to a GET for a URL that exactly matches the POST action URL, the browser decides it is in a redirect loop and refuses to do the GET. If you want to use the redirect aspect of $Web_Form_Done with such versions of Netscape Navigator or Netscape Communicator, they can be "tricked" into working by adding an octothorpe (#) character at the end of the action URL, as in:

HTML <form method="POST" - action="{$Web_Form_Action.#"> . . . rest of form </form> </body> </html> END HTML * Send the form %rc = $Web_Form_Done

This doesn't seem to cause any problems with other browsers, so it is a safe tactic if you are unsure about whether any end users will be using a version of Netscape with this bug.

Setting timeout values

The redirect timeout and POST timeout are very different. Since browsers automatically respond to a redirect, a long delay between sending a redirect and receiving the associated GET suggests either a network problem or a problem with the browser. Therefore, a fairly aggressive redirect timeout (approximately 60 seconds or less) is in order.

Since the POST timeout is the maximum amount of time the end-user will be given to fill in a form and POST it, this timeout is, in effect, a session inactivity timeout: if the user takes more than the indicated time to fill in the form, the persistent session is terminated and the user's POST will simply restart the request.

Unfortunately, persistent web applications have no way of knowing if or when a user has navigated away from the application by clicking on a hypertext link on one of the application pages, by backpaging through her browser cache, by selecting a browser bookmark, or by explicitly typing in a URL. There is also no way to determine when a user exits the browser or simply shuts down the workstation. For these reasons, it is probably a good idea to make the wait timeout of the POST somewhat conservative. It is also probably a good idea to keep the default setting of 1 for the port definition parameter MAXIPSES. This limits the number for persistent legacy sessions per user to one.

In addition, while it is possible to specify a separate POST timeout on each $Web_Form_Done, it is probably better to specify a value of 0 and to use the FORMPOSTWAIT default of 900 or the value specified on the port definition or ON rule. This ensures a consistent session timeout value within an application or web server, and it makes it easy to change the session timeout as needed.

Identifying the request user

$Web_Form_Done depends not only on URLs being consistent between GET and POST requests, they depend on requests by different users being distinguishable. $Web_Form_Done will use every bit of data at its disposal to distinguish requests and so prevent one user from seeing another user's data. Among these bits of data are:

  • The URL
  • The userid of the user POST'ing the form. Obviously, this is not of much use for public requests running under the WEBUSER userid.
  • The IP address of the browser. This cannot be used if the VARIPADDR parameter is set on the port definition. It is also of very limited utility if most users access the port through a single proxy server.
  • The identifying cookie set because of the WEBCOOKID port definition parameter.

Persistent sessions work best in a situation where every user logs in under a different userid. In situations where this would not be the case, such as public applications, it is recommended that the WEBCOOKID parameter be set. While it might be possible to prevent users from seeing each other's persistent session pages by generating unique URLs (perhaps by including time stamps in them), unless the actual end-users can be identified through userids or WEBCOOKID cookies, there is a great risk of an individual user accidentally or maliciously producing a large number of orphaned sessions.

Using check fields

When using $Web_Form_Done with a non-negative POST wait time, that is when using a persistent session, the URL for the persistent session might produce several different forms, all of which get posted to the same URL. This is not a problem when things are working well and users are cooperative. However, if a user were to backpage to a previous form in the persistent session and then POST it, $Web_Form_Done would have no way of knowing this has happened. It would return to the application with one form posted while the application expected another. This could cause serious application problems if the application is not written to deal with the situation, and in any case, an application coder would prefer not to have to worry about this.

To solve this forms problem, Janus Web Server provides the check field and check value parameters on the $Web_Form_Done call, which can be used as follows:

  1. Each form sent to the browser as part of a persistent session must have a hidden field that contains a value unique to that incarnation of the form, typically a time stamp.
  2. The name of the hidden field and its value are passed to $Web_Form_Done, which checks the value of the field when it receives a POST.
  3. If the value of the field is not the same as that specified on the $Web_Form_Done call, Janus Web Server resends the current form on the URL. It assumes that the user has backpaged and POST'ed, so displaying the most recent page in the persistent session is the most logical action.

The following code demonstrates the use of such a hidden check field:

%TIMESTAMP = $Web_Date HTML <form method="POST" - action="{$Web_Form_Action."> <input type="hidden" name="validate" - value="{%TIMESTAMP}"> . . . more form stuff END HTML %rc = $Web_Form_Done(0, 0, , - 'validate', %TIMESTAMP)