Home-ProLib Software GmbH

 

Release Notes

Home-ProLib Software GmbH
  Index
  News
  Description
  Documentation
  Demo pages
  Weblinks
  Download
  Contact
  imprint
  e-Mail
3.0.609
=======

Improved stability. Dialogs are now detected properly. [1214]



3.0.607
=======

Build 601 to 606 didn't contain updated files for all C++ components (AFP3.DLL, AFP3Service.EXE). These are now updated. [1212]



3.0.605
=======

The default runtime is now VFP 9. This affects two customer groups:

- For AFP 3.0 Express users the VFP 9 runtime replaces the VFP 8 runtime version. You don't have to change anything in order to activate the VFP 9 runtime. If you install a beta version, you should ensure that the VFP 0 runtime is installed, too. Due to the slight differences between VFP 9 and VFP 8 we recommend that you test your web application after installing this build.

- AFP 3.0 users are only affected if you haven't specified a runtime in the configuration file. As the ControlCenter always adds the runtime setting, this applies only to users that edit the configuration file manually,
[1211]



3.0.604
=======

Fixed a memory leak in APF3.DLL. [1209]



3.0.602
=======

Fixed an access violation in ISAPI.DLL that under certain circumstances caused IIS to unload the application pool. [1201]



3.0.600
=======

FIX: Saving the configuration file in the ControlCenter caused an error. [1197]



3.0.599
=======

The status page in the ControlCenter now defaults to the engine specified in the configuration file. The list of engines indicates which version of VFP is used (EXE9, EXE8, etc.) [1127]



3.0.598
=======

Fixed a crash in Beta version 3.0.597 [1189]



3.0.597
=======

Fixed some performance issues. [1185]



3.0.596
=======

INCLUDE files can now contain events. [557]



3.0.593
=======

Server.JSEncode("string") encodes a string as JavaScript requires it. That means that " is converted to \", \ to \\ and CHR(13) and CHR(10) to \n.

Server.JSEncodeLiteral("string") work like Server.JSEncode, but also adds double quotes around the string and splits long strings into multiple strings. [1177]



3.0.590
=======

FIX: Objects in AFP applications and plugins could hang the AFP engine upon shutting down if an error occurred. [1165]



3.0.587
=======

FIX: A potential way for sessions variables to sneak into another session has been fixed. Session variables are now released after the PageCallAfter event. [1162]

FIX: Duplicate key error on MySQL in SetSessionData method. We recommend using MySQL 4.1.0 or higher with AFP. [1162]



3.0.586
=======

The AFP 3 client is now available as a VFP 8 and VFP 9 compiled DLL. If your application is written in VFP 9, you can ship AFP3Client.9.DLL instead. Please note that you can only install one of the two versions on one machine. [1153]



3.0.585
=======

AFP now compiles files approximately 20% faster than before. [1136]



3.0.584
=======

Request.Form("formvar",-1) returns a list of all values for the specified form variable separated by CHR(13). Request.Form("formvar",-2) returns the count of a single form variable.

The C24_Fox plugin now supports returning multiple form values. As in AFP 2.x this happens automatically. [1135]



3.0.583
=======

Using Fox.Call now preserves cookies and headers just like AFP 2.x [1129]



3.0.582
=======

AFP bases the cache name on the physical location, if the web server provides a value in the PATH_TRANSLATED server variable. This is the case when you use IIS with script mapping. As a result you only get one cache entry per physical file, no matter what host name or URL the user specified. Previously, the cache was filled up with various copies of the same file using different server adresses. [381]

New Server.Build() function compiles an AFP page and puts it into the cache. The most common scenario for this function is re-compiling all pages after you have installed an updated of AFP or your application:

LOCAL laDir[1], lnFile
lcDir = "C:\inetpub\wwwroot\myapp\"
FOR lnFile=1 to ADIR(laDir,lcDir+"*.AFP")
Server.Build( lcDir+laDir[m.lnFile,1], "PAGE" )
ENDFOR

The first parameter is the full path and file name of the file to compile. The second parameter is optional and specifies the type of document. Currently, only "PAGE" and "APPLICATION" is defined. When the parameter is omitted, AFP uses the file extension to determine the type automatically. [381]

Server.Info() displays a list of all loaded PlugIns. [500]

The process identiy is now part of the cache name. The AFP service and the debug instance do not share the same FXP files anymore. Consequently, you can now start thew debug instance without stopping the service and without getting the dreaded "Cannot create file..." error message. [984]



3.0.581
=======

FIX: The VFP 9 based engine caused crashes on Windows 2003 Server when the C24 plugins have been loaded. This has been fixed. [1101]

FIX: AFP 3 service might crash when shutting down AFP [1103]

The default for SQLSetProp("DispLogin") is now 3 to avoid any login dialog by default. [1108]

FIX: When a the line second to the last one terminated with a semicolon and the last line started without a tab or a blank, AFP copied both lines together without a separating blank causing syntax errors. This has been fixed. [1110]

FIX: session thread had a handle leak causing handle count and memory consumption to increase until AFP 3 was restarted. This might be related to the observation that AFP sometimes doesn't restart a new thread if one is needed. [1111]

The build engine supports a new option to disable the generation of code that checks for a new version of a file. When you set this option to .F.:

_AFP.SetOption( "build/check-dependencies", .F. )

all files that AFP compiles into the cache do not contain code to check for modified files. Even when you switch the setting back to .T., these files are not updated automatically. You need to delete the cache in order to force AFP to recompile the page.

This setting is meant for production servers to increase performance when pages change seldom and deleting the cache is possible as part of the deployment process. [1114]

The AFP service now supports additional registry settings in HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\AFP3\Parameters:

Debug, DWORD: Set to 1 to enable debug mode. Set to 0 to disable debug mode. In debug mode, the service reports any activity via DBGVIEW.EXE from http://www.sysinternals.com. You would enable debug mode when there's a problem with the service.

DebugLog, String: In addition to DBGVIEW, the AFP service can write messages into a file if you specify a valid, fully qualified file name here.

Server, String: Specifies the fully qualified name of the EXE that is launched as the server. By default, the AFP service looks for AFP3.8.EXE in the same directory as the service.

Options: Specifies the options passed to the AFP server in addition to the config file. The default value is "server silent". "server" is mandatory if you use the default EXE. For a detailled discussion of all available options please refer to the documentation or online on http://www.afpages.com/docs/en/.

Should the service be unable to start, it now returns an error code back to Windows. If you start the service from the Services console, Windows displays this error code in a messagebox. [1116]



3.0.579
=======

FIX: Method code from classes is not compiled into the AFP document (introduced in build 577). [1100]



3.0.578
=======

FIX: The C24 layer now supports COLLATE sequences different from MACHINE. [1096]

FOX.cVersion is now "3" to allow for conditional code that works in AFP 2.4 as well as in AFP 3.0 [1097]

AFP 2.4 allowed to access FOX.aFormVar and FOX.aParam without specifying an index. The C24 layer now supports this, as well. [1098]



3.0.576
=======

Server.RGBtoHTML() converts any RGB color code to its corresponding HTML code:

<body style="background-color: <%?Server.RGBtoHTML(RGB(255,0,0))%>;">

Server.HTMLtoRGB() converts HTML colors back to RGB color. The function understand the numeric format #RRGGBB as well as most clear text color names such as Server.HTMLtoRG("DarkOrange") [863]

FXP files are now created with the ENCRYPT option. A new option controls whether PRG files are deleted from the cache directory immediately after compilation:

_AFP.SetOption("build/keep-prg-files",.F.)

The default setting is .T. to keep PRG files in the cache directory for debugging purposes. For security reasons you might want to delete PRG files from the cache to make it more difficult to obtain the sources of your application.
[1087]



3.0.573
=======

FIX: = is not ignored anymore [1083]



3.0.572
=======

FIX: Error when building pages in Build 571. [1083]



3.0.571
=======

FIX: ?, ?? and = can now be broken across multiple lines. Previously, this caused a syntax error when AFP compiled the page:

? "hello " + ;
"world" [741]

FIX: #DEFINE statements are ignored in the HTML part of an AFP document. They still work as usual in the code part that is enclosed in <%...%>'s. [853]

ENDPROC/ENDFUNC are not required anymore at the end of procedures. Just like in regular VFP programs, you can now end a function with a plain RETURN statement. This should make it easier to incorporate existing PRG based classes into .code files. [1080]



3.0.570
=======

Session.cQueryStringDelimiter defines the delimiter used by Request.QueryString() and Session.Url() to separate parameters in a URL. The default is "&". When using the C24 plugin this setting must be "&". [920]



3.0.569
=======

FIX: ThreadState.tCreated is now the DATETIME() value of the creation of a thread [1049]

The ControlCenter now displays the process ID and thread ID of all AFP engines to enable you to link resource usage to a specifc AFP page. [1061]



3.0.568
=======

The RemoteControl object provides access to the AFP server. Inside an AFP page you obtain a reference to the object with

RemoteControl = Server.CreateObject("RemoteControl")

The RemoteControl object is available in the AFP3Client object. However, it requires an NT based operating system. You obtain a reference with:

oClient.RemoteControl

The RemoteControl object provides a number of methods. They are the same that the ControlCenter uses:

NewEngineThread(cHost): Creates a new engine thread. cHost is EXE7, EXE8, EXE9 or MTDLL. On Success NewEngineThread returns a numeric thread ID, and 0 on failure.

TerminateThread(nThreadId): Terminates the thread. The numeric parameter is one of the values previously returned by NewEngineThread or NewThread.

GetStatus(): Returns an XML String with the current status of the engine. Use XMLTOCURSOR() to create a FoxPro cursor with the following fields:

- nThreadID: ID you can pass to TerminateThread to kill a thread

- cStatus: Current status (BUSY, IDLE, STOP, START, ERROR)

- cStateInfo: Additional info provided by the thread. An engine thread usually provides the currently executed page.

- nHits: Number of times the thread switched into IDLE mode. For engines the number is therefore one higher than the actual number of hits.

- nDuration: Duration of the last BUSY state.
cDesc: A description of the thread name. AFP engines use this to distinguish MTDLL, EXE and debug versions.

- tLastActivity: Last time the thread updated its activity timer. Usually threads update this counter every 30 seconds. The watch dog uses this value to determine if a thread hung.

- tCreated: Time when the thread was created

- nTID: Windows Thread ID

- nPID: Windows Process ID

newThread(cHost,p1,p2,...): Creates a new thread. cHost specifies the host (EXE7, EXE8, EXE9, MTDLL). The remaining parameters are the same as those for AFP3.n.EXE. However, you cannot specify a different afp.config file. The new threads inherits the current one. The following options are provided automatically when creating a new thread: verbose, debuglog, serverpid, threadid. If you specify any of these, you might encounter the following issues:

- verbose: Settings are added to the current settings. You cannot specify a level less verbose than the current thread.

- debuglog: The new value overrides the current debuglog setting

- serverpid: The new value overrides the current debuglog setting. It's not recommended to provide a different value as this impacts stability.

- threadid: The new value overrides the current value. It's not recommened to provide a different value as this impacts stability and the status reports from the AFP server.

Additionally the RemoteControl supports two properties:

cComputer: Specifies the computer to connect to. The default is ".". Other values are officially not supported. To connect to a different computer, you need Windows file sharing access (SMB, WINS, NETBIOS). The current account must have remote logon privileges on the destination machine.

cChannel: Specifies the AFP channel. AFP3 currently only supports the "AFP3" channel. [828]

The VFP9 based engines produce a 16-char session ID string that consistst of the digits 0-9 and letters A-F. Previous versions produce a 44-character string consisting only of digits. Both versions base on GUIDs and are therefore globally unique. [986]

FIX: Session.IsNew() now returns .T. when the session is created automatically. [1026]

FIX: Initial two backslashes in path names are not removed anymore. [1073]

AFP3Debug.DLL is the debug version of AFP3.DLL. Install it in place of AFP3.DLL to trace down problems with your AFP installation. The debug version displays additional debug message. To view this messages use DBGVIEW from http://www.sysinternals.com. [1074]



3.0.567
=======

A new server variable AFP_ISAPI contains the filename of the AFP3.DLL that the webserver actually uses. [301]

AFP3.DLL limits the amount that can be posted to an AFP application. The default is a little less than 16 MB which is the maximum that the AFP engine can handle. With the UploadLimit setting in the AFP3.INI file, you can limit this even further:

[AFP]
UploadLimit = 100000

if a request (headers and body) is larger than 100,000 bytes, the request is rejected with an HTTP 500 error message.

Since IIS cancels the transmission of the file, the client might display a DNS error message instead of a "nice" HTTP 500 error message. AFP logs a UPLOAD_TOO_LARGE error into the log file of the web server, if the web server supports this. [955]

The VFP 9 engine is now available as a MTDLL and debug version. [979]



3.0.566
=======

Reactivated VFP 9 beta engine. The current beta runs till January 31, 2005. The final release will be available under the AFP subscription model. [979]



3.0.565
=======

FIX: Fixed error "class definition CPLUGIN not found". [1059]



3.0.550
=======

All AFP objects have a new method Elapsed. It receives the start time in seconds as the first parameter and the interval in seconds as the second parameter. When the intervall elapsed the function returns .T. Elapsed handles the rollover at midnight correctly:

LOCAL lnStart
lnStart = SECONDS()
DO WHILE NOT Server.Elapsed(m.lnStart,30)
* Do something for 30 seconds
ENDDO [997]

FIX: Server didn't create new instances after midnight until one instance has been created manually in the ControlCenter. [997]



3.0.549
=======

The CONFIG object now uses MSXML 4.0 for all its operation. This requires that all queries against XML using GetValue, GetValueEx or AGetNodes are valid XPath syntax. Previously, these functions also accepted the very similar XSLPattern syntax. [1016]



3.0.547
=======

For PostgreSQL use the following connection string:

connectionstring="Driver={PostgreSQL};Servername=localhost;Database=AFP3;Port=5432;UID=postgres;cx=1A103AB" [991]



3.0.544
=======

The following connection string connects to a MySQL database. Modify the user name and password as needed:

storage="mysql" connectionstring="DRIVER={MySQL ODBC 3.51 Driver};SERVER=localhost;PORT=3306;DATABASE=AFP3;OPTION=19035;UID=AFP3;PWD=AFP3" [991]



3.0.541
=======

AFP now support MySQL and PostgreSQL as session storage in addition to MS SQL. For MySQL the script is "session_mysql.sql". The storage identifier in the afp.config file is "mysql". For PostgreSQL the script is session_postgresql.sql" and the identifier is "postgresql". [991]

When an error occured while the AFP session management tried to access the SQL server, the error message now contains additional details provided by te SQL server. This makes it easier to locate the cause for the problem. [991]



3.0.540
=======

The service waits until the AFP server shut down. This should prevent hanging instances of AFP3.x.EXE after the service had terminated. [806]



3.0.539
=======

AFP now supports MS SQL Server as a session data storage. The SQL server stores the session timeouts (session.dbf) as well as all smaller session data files like the session variables. Files up to 8000 bytes (subject to change) are stored into the database, larger files are placed on the harddisk as before.

To enable SQL server support you need to create a database on the SQL server. The AFP 3 root directory contains a Session_MSSQL.sql script file that creates the required tables. In the afp.config file change two attibutes of the session tag:

storage="mssql". The default value is "vfp". This setting defines the storage mechanism. Only VFP and MS SQL are currently supported.

connectionstring="DRIVER=SQL Server;SERVER=(local);Trusted_Connection=YES;Database=AFP3". This setting defines the connection string that AFP uses to connect to the SQL server. The connection string above applies when the SQL servers runs on the same machine as the web server, the database name is AFP3 and the AFP account has access to the SQL server in order to use a trusted connection (recommended). You can change this as needed.

When AFP uses SQL server for session storage, it does not attempt to create the Session.DBF file, at all.

AFP relies only on the clock of the SQL server to maintain session time outs. If you run AFP in a cluster and their clocks are not synchronized, you now don't have any side effects as with the VFP based storage system. [991]



3.0.538
=======

All ActiveX controls in the AFP 3 ControlCenter have been replaced by native VFP controls. This doesn't change any functionality, just the look&feel of the interface [992]

A new page has been added to the ControlCenter. The Request pages allows to specify the content of Request.cData and Request.cForm. By clicking the "Submit" button you can send this request to the AFP engine. AFP will process this request just as it would if the rrequest came from the web server. The result including all HTTP headers is shown in the Browser area.

This form can be used to test your AFP documents using different input values, to verify that your page produces the output you expect and to test if AFP itself is working properly. The form doesn't require a web server and therefore works as soon as AFP is working. If you get results using the Request page, but not using a web browser, there's most likely a problem with the web server configuration. [992]



3.0.537
=======

Keeping engines running for a long time can cause performance degradation. Therefore, AFP 3 now defaults to dynamic approach. Three attributes have been added to the server tag in the afp.config file:

max-hits: specifies the number of hits that an engine may execute. Once the maximum number is reached, the engine terminates. "0" means no maximum number specified. The default is 2000.

max-uptime: speficies the total time in seconds that an AFP engine is allowed to run. After this limit is reached, the engine terminates itself, even if the hit limit or the idle timeout has not been reached. Use 0 to indicate that there should be no maximum up time. The default is "0".

max-idle: Specifies the maximum time in seconds that an engine can be idle (not processing any requests) before it automatically terminates itself. This setting is meant to avoid wasting resources on the server. The default is 900 or 15 minutes.

These settings play together with the max-threads and min-threads setting. If an instance terminates itself and the number of engines goes below the level specified by min-threads, AFP automatically launches a fresh instance. [772]

Each AFP engine keeps checking if the AFP server is still running. If it has been terminated, for instance, by the AFP service, the instance terminates itself. This should catch those hanging AFP engines that weren't terminated by the server on time. To implement this a new setting has been added to AFP3.EXE:

serverpid:nnnn

nnnn is a Windows PID. The AFP engine only runs as long as this process is running. [806]



3.0.535
=======

FIX: Hostname validation crashed server when the hostname list was full. [976]



3.0.533
=======

FIX: Uninstalling the C24 plugin without removing the virtual tag doesn't cause an error anymore. [978]

Changes in the VFP 9 version of AFP:

- no 64 KB limit for web pages. We've tested AFP with web pages up to 11 MB.

- No limitation in number form variables.

- In order to obtain the most recent values, AFP needs to lock the record in the session table. This impacts performance, especially on Novell servers. With VFP 9 the new SET REFRESH TO n,-1 setting is used. Locks are not used for this, anymore.

- VFP 9 contains MTDLL improvements. Scenarios that caused AFP 3 to hang with the VFP 8 MTDLL runtime now properly report an error with the VFP 9 runtime. Reporting should work better, as well. Please let us know if you can't get the report writer to work in the VFP 9 MTDLL environment. [979]



3.0.532
=======

AFP now supports the VFP 9 public beta. In order to use the VFP 9 engine, you must install the VFP 9 public beta on your web server (http://www.microsoft.com/downloads/details.aspx?familyid=23fbc57b-93b0-4cb7-b376-53ca04fca159). Because this is beta software, we do not officially support the VFP 9 based AFP engine. We strongly encourage against installing VFP 9 on a production machine. The release version is meant for testing only! Only one version of the MTDLL engine can be active at a time. If you want to use the VFP 9 version, please use REGSVR32.EXE to register AFP3Engine.9.DLL. To switch back to the VFP 8 version, please register AFP3Engine.DLL. [979]

The new cleanup attribute of the session tag in the configuration file can be used to specify the cleanup interval in seconds. An interval of 0 disables the cleanup thread completely. [980]



3.0.531
=======

FIX: CleanUp thread does not delete afp.config anymore (introduced in 3.0.530) [975]



3.0.530
=======

New function Response.Flush(). Sends the current response back to the web server and browser. Response.Flush() can be called once per page. After Response.Flush() is executed, the client sees the result page and the web server closes the connection. However, your AFP code continues to run. You use this manly, when

- The web page starts a long process like creating a PDF file or performing an import. You can immediately send back a response to the client that either contains the like to the result file, or is a redirection to a page that periodically checks for the progress of the file, or simply is a notification page that the process has started.

- You want to terminate this instance of AFP to free up resources. If specified in the afp.config file, new instances are created automatically if new requests come in. [681]

Error 1705 (file access denied) in CCache.GetCurrentCacheName fixed. [773]

New method Server.TryRepeatForSeconds tries to execute function cFunction for the time specified in nSeconds until the function completes without errors. You can use this if you need to open a file exclusively:

lOK = Server.TryRepeat( nSeconds, cFunction, @rRetVal [, uParam1, ...] ) [773]

SessionDirectory.Purge() now accepts a numeric parameter. This parameter specifies the maximum time in seconds that the method is executed. [858]

FIX: Fixed various issues with cleaning up sessions. The process itself has optimized and now performs significantly faster than before. As a safeguard, the cleanup process has a timeout of 10% of the interval (that is, 18 seconds). This avoids that the cleanup process takes over the CPU and prevents regular requests from being served. The code doesn't use ADIR() anymore and therefore won't break on session directories with more than 12500 files. [858]

The hostnames specified in the configuration file are converted according to the same rules as hostnames coming in as requests. You therefore don't have to enter the normalized version, rather can enter the domain name in the form you are used to, like www.afpages.com. [948]



3.0.525
=======

The Voodoo PlugIn now automatically supports the Voodoo Extended Package (voodooex.prg). Install Voodoo as described in the manual. Then copy voodoo.fxp and voodooex.fxp into the AFP PlugIn directory. [952]



3.0.524
=======

As a licensed AFP 3 user you can use the evaluation version to develop AFP applications. To completely disable the evaluation reminder, you can use the allow-localhost attribute of the license tag in the afp.config file

<license allow-localhost="true"><key...></license>

Setting this attribute to "true" or "yes" disables the evaluation screen for http://localhost/ and http://127.0.0.1/ requests when the client is HTTP 1.1 compliant. [951]



3.0.523
=======

AFP doesn't attempt to create a session table until a page requests a session id. To disable session handling in AFP completely, you need to disable HTTP and AFP cookies in the configuration file and include the following lines in the PageCallBefore event for either the application or each page:

DOCUMENT.lSaveVariables = .F.
DOCUMENT.lLoadVariables = .F. [765]

When shutting down AFP all threads are terminated within 15 seconds. This avoids dangling AFP3.x.EXEs when more than two threads are unresponsive and the AFP 3 service is used. [806]



3.0.522
=======

The AFP server module provides a feature to dynamically create threads. The ISAPI gateway uses this feature to request a new instance of the AFP engine if it cannot connect to an existing one. This behavior is controlled by two new settings in the afp.config file:

server/max-threads="nnn": Maximum number of engine threads that the server keeps running. If the ISAPI gateway requests a new instance, an engine is launched unless there are already as many threads running as are specified in this setting. The default is server/threads.

server/min-threads="nnn": Every 10 seconds the server validates that all threads still exist. If the number of running engines falls below this threadshold, the server creates new engines to reach this value. The default is 0. If you specify a value larger than 0, you have to stop the AFP service in order to stop requests, because AFP keeps creating new instances if you kill them in the taskmanager.

Both settings are available in the ControlCenter on the Server tab. [523]

CHG: The nThreadID parameter of all thread related methods has changed to uThreadID. In future releases it will be replaced by a non-continous string. To obtain a list of all running threads created by a threadserver, a new method has been added: ThreadServer.AThreads(raThreads). This method populates an array with all running threads of a particular thread server and returns the number of threads. Future versions will return a list of all threads belonging to the same communication channel. [524]

Killing a thread now properly removes the entry from the status list in the ControlCenter. Terminating a thread from the ControlCenter has an immediate effect on the list, killing a thread from the task manager causes an update of the list after 10 seconds or less. [737]

FIX: The watchdog caused a problem when trying to launch a new instance. Now the watchdog is only responsible for removing hanging threads. A new thread is automatically launched when either the ISAPI requests a new instance, or when the server/min-threads limit has been reached. [830]



3.0.521
=======

FIX: Changes in files included into .code files are now automatically detected. [943]

Session.GetSessionData() now takes an optional second character parameter that is returned if the session file didn't yet exist or couldn't be read. [945]

If two events in the afpa.code and in the afp.code file share the same name, AFP now inserts the application level code before the page level code. [946]



3.0.520
=======

The new server/hostnames configuration settings allows to specify a comma separated list of hostnames. This setting is used to initially populate the list of hostnames. It's not possible to add more host names this way than there are licenses. If there are host names remaining, these are dynamically filled as requests come in. The control center allows to change this setting on the server tab. You need to restart AFP in order for these settings to take effect. [672]

FIX: AFP displayed the name of the error page instead of evaluating the error page. [939]



3.0.518
=======

The new Response.nContentLength property can be used to control the Content-Length HTTP header that is sent back to the server. If you encode the response in any way (like compressing it) you need to set it to the original length before compressing Response.Body(). The default is NULL, which makes AFP use the actual size of the response body. [942]



3.0.512
=======

When running the debug engine, you can now suspend program execution when an error in your code ocurred. [899]

The ISAPI gateway reports all errors into the event log. If the event log cannot be opened, the error is reported as a debug string. If the ISAPI gateway doesn't seem to forward requests to the AFP engine and you cannot find anything in the event log, please download DBGVIEW from http://www.sysinternals.com, launch it, restart your web server and try again. If you need assistance understanding the output listing, please contact ProLib support. [923]



3.0.511
=======

HTTP_X_FORWARDED_FOR and HTTP_VIA are available as server variables if provided by the web server [856]

ServerVariable REMOTE_IDENT available if provided by the web server. [857]



3.0.510
=======

The following (yet undocumented) page events have been dropped from the product (please contact chrisl@prolib.de for assistance if you had used any of them)

- PAGE.EVENT_Load
- PAGE.EVENT_Recompile
- PAGE.EVENT_PageCall
- PAGE.EVENT_Init
- PAGE.EVENT_AppCall [921]

FIX: Events in application-less pages were ignored. [921]

The strict separation between application and page events has been lifted. Events can be defined in the afpa.code file (valid for all pages of the application) and afp.code (valid only for a specific page). In the afp.code file you can now define application specific events, as well. If you define the same event in an afp.code and an afpa.code file, both procedures are combined into one. The order, however, can be random. The following events are safe to be used in an afp.code file:

Event_PageBefore
Event_PageAfter
Event_PageCallBefore
Event_PageCallAfter
Event_PageError (same as Event_Error)
Event_LoadVariablesBefore
Event_SaveVariablesAFter

Other events can be included, as well. Due to their conditional nature they might not behave as you expect, though. [921]



3.0.508
=======

FIX: Fox.lError remains .T. when an error occurred in Fox.oFoxDo.DoIt(). [905]

FIX: form values containing encoded "&" characters caused problems when accessing FOX.cForm. [906]



3.0.505
=======

You can now use the same parameter name in nested INCLUDE files. [911]



3.0.502
=======

Session.Url() without parameter does not anymore return the URL including querystring. This feature added to build 483 has been removed due to backward compatibility issues. Instead, you can now use the new Session.PostbackUrl() function that fulfills the same purpose. This function is mainly designed to allow a form to return to itself without having to know anything about the querystring values:

<form action="<%?Session.PostbackUrl()%>"> [903]

The INCLUDE compiler command allows to pass parameters to included files:

*!<[INCLUDE: "page.afpi", "Alias()"]>

In the included file (page.afpi in this example), you define parameters using the new PARAMETER directive anywhere in the code and then using the parameter:

*!<[PARAMETER: ccAlias]>
USE IN ccAlias

The expression in the INCLUDE line is evaluated. As a rule of thumb you need to put all parameters in an additional set of quoation marks. To insert the compile datetime into the inserted document you can use:

*!<[INCLUDE: "page.afpi", ["]+TTOC(DATETIME())+["]]>

IMPORTANT:include file parameters are not variables! Rather whatever you specified as the parameter is used to replace all occurrences of the parameter in the inserted program. If you have a file

*!<[PARAMETER: ccParam]>
ccParam = "Hi there"

and you call it like this

*!<[INCLUDE: "page.afpi", "Request.QuerySTring([param])"]>

The resulting file after merging the include file into the main file looks like this. Since this is invalid code, you get an error at compile time:

Request.QuerySTring([param]) = "Hi there"

While multiple INCLUDEs can be nested, the same does not apply to include parameters. If an include file at a lower level uses the same parameter name as the one above, it overwrites the parameter value. This is because internally these parameters are converted into #DEFINE statements. [911]

Objects can be persisted as XML session files. Usage:

<%
local loData
loData = CreateObject("Custom") && Empty class in VFP 8
loData.AddProperty("Prop1","Hi")
loData.AddProperty("Prop2",123.45)
Session.GetObject(loData,"data")
* ... modify loData here
Session.SetObject(loData,"data")
%>

The purpose is to have a place to store page or form specific values without having to include them into the URL as a querystring, as a hidden field into a form (both can be hacked) or to create a session variable which would be global to the entire application. Internally, these functions create session files that contain all custom properties as XML.

Subobjects are not supported. Only character, numeric and boolean properties are supported. Objects with custom methods are not supported. [913]



3.0.500
=======

All modules except for AFP3.7.EXE now require the VFP 8 runtime. This shouldn't be an issue on any supported platform except for the AFP3Client.DLL. If you ship this with your application, you must include the following files in the setup:

vfp8t.dll
vfp8renu.dll (or any other language version)
msvcr70.dll
gdiplus.dll [896]



3.0.495
=======

The Voodoo PlugIn now automatically supports the Voodoo Extension Package if it's available. [894]



3.0.483
=======

The new Document.lExecutePage property controls if a page is executed:

PROCEDURE Event_PageBefore
IF NOT gcUser == "ADMIN"
Document.lExecutePage = .F.
Response.Write( FILETOSTR(File.FullPath("noaccess.htm")) )
ENDIF
ENDPROC [889]

Session.Url() called without any parameters returns the URL of the current page including any querystring variables. Using the result of this function in a form action should be sufficient to implement a postback to the same page. To get just the name of the current page including the session IDs, use Session.Url(""). [891]



3.0.481
=======

FIX: When no engine is specified, the ControlCenter configuration page assumed "VFP7" as the engine even though "EXE7" is correct. [886]



3.0.480
=======

FIX: Response.DateRFC1123 and Response.CookieDate accept Date and Datetime parameters. In case of dates the current system time is used to return a complete string. When passing other types the current time stamp is returned. [876]

FIX: Response.Expires accepts value of type Date and/or Datetime. Other types are converted to current system time. [877]



3.0.479
=======

FIX: GetPreviousURL() did return an empty string when the URL didn't contain a parameter. [878]



3.0.478
=======

FIX: The Voodoo PlugIn now properly initializes the page object. Failing to do so had previously caused problems with data binding in Voodoo. [875]



3.0.469
=======

AFP3.EXE is now AFP3.8.EXE. [851]



3.0.466
=======

FIX: Thanks to Jorge Peréz we now have a Spanish version of the ControlCenter. When the regional settings of your computer are set to Spanish, you automatically see the Spanish version when launching the ControlCenter. [848]



3.0.465
=======

FIX: Session variables of abandoned sessions cannot be recovered by pasting the link with the session id into the address line of the browser. Previously this made the login sample fail to completely log off a user. [732]

FIX: For security reasons AFP never accepts a session ID passed by the user if the session ID is not a valid session ID. This has been the case in AFP 3 mode all the time, but was handled incorrectly by the C24_Cookie PlugIn. [821]

AFP3Debug.prg now senses the version of VFP and launches the appropriate AFP instance. [843]



3.0.464
=======

The REQUEST_URI server variable is now available when the web server provides it. Currently this is the case with Apache. [829]

Extended the options of AFP3.EXE and AFP3.7.EXE:

verbose:1 = print system, error and informational messages
verbose:2 = print above plus requests
verbose:3 = print above plus Keep Alive signals

debuglog:file = log all messages into the specified log file. The message log is not a replacement for the regular event log. Its purpose is to support debugging. [836]

New function _AFP.SetOption() allows to set options that directly impact the way AFP processes requests. The syntax is _AFP.SetOption(cOption,uValue). The option is case-sensitive. The value depends on the option. Unless otherwise state, none of the options here is officially supported. If you encounter problems when using these options, try again with the default values before submitting a support request.

performance/use-full-cache-path: default .T. When .F., FXPs in the cache are called with just the cache name. This results in higher performance, but requires that the cache directory remains inside SET PATH at all times.

performance/clear-fxp-cache: default .T.. When .F., no ClEAR PROGRAM is issued after each request. This increases performance, but mgiht have caching effects on existing applications.

performance/process-messages: default .T. When .F., AFP does not process windows messages in the idle loop in an out-of-process engine. This reduces CPU usage, but might have unwanted side effects like not beeing able to stop AFP.

system/debug-log: default empty string. Specify a file that contains all the debug information usually printed on the _SCREEN. [837]



3.0.463
=======

This build should not hang anymore when stopping the service. Please let us know should AFP stop responding when you should the service down. [806]

FIX: "LOPLUGIN is not an object" error fixed when C24_FOX PlugIn is not loaded. [819]



3.0.462
=======

FIX: The Response.Cookie() syntax has been dropped as it never worked. To add a new cookie, the Response.AddCookie() function is now working. The work around using Response.AddHeader() is not needed anymore. To modify an existing cookie the SetCookie and GetCookie functions have been added:

Response.AddCookie("demo","this is a value",date()+10)
Response.SetCookie( "NEVER", "demo", "Expires" )
? Response.GetCookie( "demo", "Path" )

The VFP 8 based AFP engines (MTDLL and EXE8) also support a ASP-like Cookies collection:

Response.Cookies.Add("demo")
Response.Cookies("demo").Value = "some value"
Response.Cookies("demo").Secure = .T.
Response.Cookies("demo").Expires = "NEVER"

Available properties in a cookie are Name (C), Value (C), Expires (C,D,T), Path (C), Domain (C), and Secure (L). The value in parenthesis contains possible types for this property. [744]

FIX: Applications are unloaded and reloaded whenever a new version is compiled. This is ensured every time a page is called. When an application is unloaded, its Event_Unload code is executed. Here you can release public variables that you have created in the Init event. Tables are automatically closed. [782]

When validating host name licenses hyphens and underscores do not count towards the host name. The domains www.myweb.de, www.my-web,de and my_web,de count as a single host name. Everything else remains unchanged. If you have multiple top-level domains (afpages.de, afpages.com) or if you have different domain names pointing toward the same web, you still need additional host licenses. [790]



3.0.461
=======

FIX: Request.SplitString() error when using SET POINT TO "," [774]



3.0.460
=======

ERROR.Encode(cText) can be used to encode strings into HTML text in error message. This method is identical to SERVER.HTMLEncode(), yet works when the SERVER object might not be available. [608]

FIX: The application ID is now correctly used. Applications with different IDs do not share variables, even when the same SessionID is used. The work around to set the APP.cID property in the Init event is no longer needed. [686]

Modifcations to the object management have been finished. The multi-threaded server as well as the service are now available. The afp.config file change to take care of the new model. The new config/afp/server/engine option decides wherer to run AFP in. Possible values are "MTDLL", "EXE7" and "EXE8". The multithreaded runtime is only available in a VFP 8 version as it requires the new TRY...CATCH functionallity to run stable. config/afp/server/isolated setting is not used anymore. VFP7.cmd and VFP8.cmd are not required to run different versions of VFP. [708]

FIX: Threads can be launched and stopped in the ControlCenter [768]



3.0.459
=======

FIX: Server.Execute() now always operates in the same datasession. Files opened in one page remain open in the other pages. [653]

Server.Level() returns the current recursion level. It's 1 by default an increases in every Server.Execute(). Server.RedirectLevel() returns the recirection level. It's initially 1 and increases on every Response.Call() and Server.Transfer(). AFP supports about 8 recursion levels and 30 redirection levels. Response.Redirect() sets all counters back to their defaults as this function causes a round-trip to the client.

You can use Server.Level() if certain are limited to the outermost level. AFP, for instance, only loads and saves session variables on Level > 1.

Server.RedirectLevel() is an easy way to prevent pages from being called directly. In pages that can only be called by other pages, but never by the user directly, you can use code like this:

If Server.RedirectLevel() == 1
Error.HttpError( 404 )
Return
Endif [745]

FIX: Server.Execute() caused empty variables. [745]

FIX: Changes to the .afpa.code file are now picked up by pages without having to clear the cache directory. [754]

ERROR.cAction="CANCEL", as well as the CANCEL command in the error handler terminate the execution of the current page, but still send back the current page. You can use this to display you own error message defined in the application instead of using the default error HTML file. [756]

FIX: server/error in the afp.config file can now contain any path qualifier like %root%. [757]

Instead of Error.cAction="" you can now use the regular FoxPro commands RESUME, RETRY and CANCEL to react in your own Error event procedures. Please note that these commands are only available in the error event itself, not in any method you can from the error event. The reason for this is that these commands are redefined in the Error event to call the SetAction method of the Error object. Outside the error event you still have to set the cAction property. [760]

FIX: You can now make the application in one directory the same as the application of the parent directory by using the following syntax:

<application>
<file name="application" relative="..\app.afpa"/>
</application> [761]



3.0.458
=======

The AFP3.Server object has been merged into AFP3.EXE. The previous syntax of creating an instance with CREATEOBJECT() and calling the StartUp/SHutdown methods therefore doesn't work anymore. Instead call

AFP3.EXE afp.config SERVER [389]

When terminating an AFP instance from the ControlCenter, the process is given a 5 second timeout to quit gracefully. After that it is killed. The ThreadServer::Terminate method has changed to allow for this option:

ThreadServer.Terminate( nThreadID, nTimeOutSec, tlForceKill ) [390]

The internal thread handling of AFP has changed. Previously, there were COM references between als instances of AFP, because this reference was used to gather one global information (which config file to use) and to release the thread. The drawback was that each AFP thread had to be created by the AFP3.Server object. And this all involved a lot of COM with lots of cofiguration and usability problems.

The new threading model moves most code into a single file, the AFP3.EXE. This file contains the whole server as well as the AFP engine, which does process the individual requests. It also contains an interface that optionally can be displayed. AFP3.EXE can be launched individually, by the AFP3Srv service and within the VFP IDE. In order to debug you therefore don't have to launch a debug engine. Just fire up VFP and execute AFP3Debug.PRG or AFP3.EXE (the prg merely calls the EXE with a few default options).

Only the MTDLL requires a COM server. Due to VFPs internal handling, the AFP3Engine.DLL file still has to contain the entire engine. As the MTDLL version requires some VFP 8 features, we don't support a VFP 7 version anymore.

The synatx for AFP3.EXE is as follows:

AFP3 <config> [server] [engine] [silent] [debug] [verbose] [threadID:9999]

server:
Launches the AFP server. This includes the cleanup thread (session timeout handling, deletion of files in the session folder), the watch dog (killing hanging instances), the server interface (launching and stopping threads) and a number of AFP engines.

engine:
Launches an AFP engine. This option works even when the AFP server is not running. This is usefull when you need to test something quickly. However, the AFP3.DLL ISAPI gateway must be running to forward requests from the web server.

silent:
When used with the SERVER option, the server doesn't display the AFP 3 form that contains the copyright text and the Cancel button. Is used from the service.

debug:
If an error occurrs, AFP displays a dialog and lets you step into the debugger, if AFP3.EXE is running in the VFP IDE. It also enables the hot keys to step into the debugger and cancel the AFP engine. If you run AFP3.EXE in the VFP IDE without this option, AFP behaves like in the runtime and doesn't stop on errors. This can be used when you want to execute in the IDE without relying on the runtimes in cases where the usage of the VFP runtimes is restricted or impossible.

verbose:
Displays additonal information, each request and errors on the VFP screen as pure text. The server displays an additional area in which information about the remote control interface and server related information are displayed.

threadID
A number between 1 and 2048. Defines in which slot the status information in the ControlCenter are displayed. Each instance must use a different ID. AFP starts assigning values beginning from 1, your own IDs should therefore be in the upper range of 1900 and above.

For simplicity, there are the following special cases

AFP3.EXE = AFP3 afp.config server
AFP3.EXE verbose = AFP3 afp.config server verbose [522]

The server now waits for all threads to shutdown giving each thread a 5 second timout. Previously, AFP had always waited 5 seconds after telling all threads to quit, even though in most cases, the threads were terminated in less than a second. If threads terminate quickly, AFP does now shut down just as quick. Restarting the service is therefore faster than previously. [554]



3.0.457
=======

The HTML object and the AFP3 client object requires a direct internet connection. Now they use a proxy, if one is configured in the Windows internet settings. Because the ControlCenter uses the same object this affects all situations where the internet activation didn't work due to a proxy. [729]



3.0.456
=======

When there's an error in the .afp file, a detailled error report is now written into the event log. [645]

Request.GetCurrentFile() returns the file name portition of the current Url. If the Url is http://localhost/samples/info.afp?sid=999..99, this function returns "info.afp". The difference to Session.Url() without a parameter is that Session.URL() always adds the AFP session id. If you need the file name without session information, you can use Request.GetCurrentFile(). [676]

When an HTTP POST request contains an unknown content-type, form variables are not parsed. The binary content of the POST request is available as

cContent = REQUEST.Form() [716]

AFP 3.0 contains a new DLL (AFP3Client.DLL). This DLL contains the AFP3.Client COM object. AFP3.Client provides features that are useful in applications on the client side to access an AFP server via the internet. You can distribute AFP3Client.DLL free of charge with your applications. The DLL is multi-threaded and requires the VFP7T.DLL.

Currently, the client object supports GET and POST requests:

oAFP = CreateObject("AFP3.Client")
cData = oAFP.HTTP.Get("http://www.afpages.com")
oAFP.HTTP.Post("http://myserver/page.afp","This is the data") [722]

The HTTP object supports a Post method to send back data to the server. You may call this function like this:

oHTTP = Server.CreateObject("HTTP")
oHTTP.Post("http://localhost/result.afp","My data")

The data portition can be up to the maximum string length of VFP which is approximately 16 MB. [724]

FIX: The Voodoo plugin returned the wrong address for postback operations on Apache servers. The fix required a change in the AFPRequest.GetPreviousURL() function. If you rely on this method, please replace it with Request.ServerVariables("HTTP_REFERER") instead. [727]



3.0.455
=======

FIX: A missing QueryString caused problems in the VOODOO PlugIn [559]

The license agreement changed. If you have a valid AFP license (AFP3.LIC file), you may install the AFP 3.0 evaluation version on all of your machines for the purpose of development and testing. This does NOT apply to the AFP3.LIC file. You may install the AFP3.LIC file on ONE machine ONLY. To make using the evaluation version easier, it doesn't display a copyright notice on every page if you request pages from http://localhost/ or http://127.0.0.1/. The 15 minute reminder has not changed, though.

The VFP 7 and 8 EULAs are part of the license agreement of AFP. Restrictions given there do apply to AFP, as well. This includes specifically platform limitations on which the runtime files can be installed, restrictions regarding decompilation, reverse enginering, export restrictions, and so forth.

This text is not a license agreement. Refer to the license agreement that comes with AFP 3.0. [688]

It's now possible to suspend applications, for example, when you need to perform some maintainance tasks. In order to suspend the application, use the code

APP.lSuspended = .T.

Any further request to this application triggers the EVENT_Suspended event. Here you can either display a message or continue by setting lSuspended to .F. When being suspended, part of the application is still executed. These are Event_Init of the application and the page, the error event of both as well as the Unload event of the application.

When the application is unloaded it looses its suspended state. Also, this flag is local to the AFP Engine. In order to suspend multiple threads, each threads needs to check some external resource (a file, an INI value) in the Init or the BeforePageCall event that enables the suspended state and check the same resource to continue the application in the Event_Suspended event. It's not sufficient to have a single page that sets this flag based on a parameter.

The Event_suspended event does have full access to all procedure in the afpa.code file. It's only executed when the application was suspended. [689]

RESPONSE.DateRFC1123(tDate) returns a data value that is compliant with RFC 1123. It differs slightly from the date format used by RESPONSE.CookieDate() which is only usable in a Set-Cookie header. [694]

FIX: In compliance with RFC 2616 AFP send2 an Expires header which is identical to the Date header in order to indicate an expired document. Previously -1 was sent in the Expires header. [695]

FIX: Build 3.0.450 did not execute the application.prg or application.afp, nor did it compile them into an .fxp. This resulted in the execution of an outdated version, or no execution at all. [701]

If you want to create a new session in a document, you can now use

Session.NewSession()

instead of the old code

Session.Abandon()
Session.NewSession( Session.CreateSessionID() ) [710]

FIX: Fox.aParam did not return values in all cases. [711]

FOX.cForm now returns either the query string or the POST body like AFP 2.4 does. [712]

FOX.lDebug now toggles ERROR.lShowError. When FOX.lDebug is .T., a detailed error report is sent to the browser, if .F., a plain HTTP 500 error is sent to the browser. This setting corresponds to the "Show error message in browser/Fehlermeldung im Browser" setting in the AFP 3.0 ControlCenter. [721]



3.0.454
=======

FIX: The AFP 3.0 service now runs on Windows XP, as well. We removed the .NET based service. The two files AFP3Srv.NET.EXE and AFP3Engine.InterOp.DLL are not needed anymore. AFP 3.0 does NOT require the .NET runtime to be installed anymore. [687]



3.0.453
=======

FIX: C0000005 error after passing invalid strings to SERVER.URLDecode() [706]



3.0.452
=======

FIX: The message "RPC Server not available" while shutting down AFP is not displayed anymore. This message indicated that one instance hung or was killed before and can be ignored at that time. [697]

FIX: The locking behavior of the session file has been improved. The error message that a record in the session file is in use by another user should not appear anymore. [697]

IMPORTANT: The watchdog feature introduced in build 3.0.451 is now disabled by default. If you need the watchdog feature, you must turn it on in the afp.config file by setting the server/watchdog value to true:

<server watchdog="true"/> [703]



3.0.451
=======

AFP does now have a WatchDog feature. If an instance of AFP does not return from the busy state within five minutes, this thread is marked as non-responsive in the ControlCenter. non-responsive isolated AFP threads are terminated forcefully and a new one is launched as a replacement. MTDLL threads are not terminated. The timeout of five minutes is hardcoded at the moment. WatchDog events are reported to the Windows event log. [103]



3.0.450
=======

FIX: error #1234 when compiling an empty event. [574]

On the Status page of the ControlCenter you can now instantiate isolated engines. Previously, only the debug engine and multithreaded enginges could be created there. [589]

The preferred way to store application specific data is now to use the SetData and GetData methods:

APP.SetData( "myName", "MyValue" )
lcValue = APP.GetData( "myName" )

The old way of using the associative Data array still works. However, due to the usage of access and assign methods internally, this might cause problems when storing object references into the application. [605]

New methods DOCUMENT.Finally(cCode) and APP.Finally(cCode). This method returns an object that executes code when it goes out of scope. You use this when you make changes to the environment that must be undone if the application returns, even in case of an error. A typical usage is:

Local loFinally
loFinally = AFP.Finally("Set Path to "+Set("Path"))
Set Path to ....

After executing the Event_PageCallAfter event or when an error occurrs anywhere during the execution of the current page, the previous path is restored. Failing to do so might cause subsequent requests to fail. The difference between DOCUMENT.Finally() and APP.Finally() lies in the datasession in which they execute the code. For most pages, APP.Finally is the correct choice. Only application-less pages must use DOCUMENT.Finally. [610]

FIX: Server.Execute() failed with error message "loCall is not an object" when called recursively. [650]

Response.Call() and Server.Transfer() can now receive query string parameters:

Response.Call( "newpage.afp?parameter=value" )

If a query string parameter is passed to the new page, this parameter overwrites the current set of parameters. If no parameters are passed in, the current set is transferred to the called page. [661]



3.0.446
=======

FIX: The Status page in the ControlCenter remained empty when being viewed in a Terminal Server session. [534]

The service does now properly handle COM security. It's not required anymore to give the AFP user default access permission to COM in general. In isolated mode you still have to grant the AFP user access to the AFP 3 out-of-process-host.

AFP now reports more errors when COM related things go wrong. If you encounter a problem when launching AFP, please send us these error reports from the Windows event log (not the event.log file!). [612]

FIX: HTTP object is now available. [623]

To manage host licenses the following methods have been added to the SERVER object:

nHostnames = GetHostnames(@aHostnames) - Fills an array with all registered host names and returns the total number of host names that AFP will accept. This number includes the number of hosts that AFP accepts (currently 3) plus the number of host licenses that have been purchased separately.

GetHostNamesLicenses() - returns the number of host name licenses. The unlimited edition returns 65000.

GetHostnamesAvailable() - returns the number of host names that AFP accepts in addition to those that already have been registered. If this number is 0, any connection from unknown host names are refused. The unlimited edition returns 65000.

IsUnlimited() - returns .T. if this is an AFP unlimited version that doesn't have any restrictions on the number of host names

Currently, host names are managed per thread separately. You might get different results in different instances of AFP if a host name has not yet been served by a particular instance. Requests are served by instances in the order of creation. All requests are served by the first instance unless it is busy when a request comes in. This behavior might change in future versions of Windows and AFP. You should not rely on this behavior. [624]



3.0.444
=======

FIX: The upload of some files didn't work right. This happened especially with long binary files or when uploading from Netscape. [621]



3.0.443
=======

When shutting down AFP3.EXE you get a clearly visible message that AFP is shutting down. This takes about five seconds. [304]

The ControlCenter now displays the current AFP 3 version. [305]

FILE.FullPath() returns file names that are relativ to the current page. For instance, if you have a data subdirectory, you can use code like this to open a table:

USE (FILE.FullPath("Data\Customer.DBF"))

this replaces the rather complicated expressions using FILE.GetLocation(). [572]

AFP requires "modify" access to the Cache, Common and Log directories. All other directories require "Read and execute" access. [617]



3.0.442
=======

FIX: The setup falsly configured AFP to store the cache directory in the common directory. The default is %root%\cache. This only affects new installations, not updates. [617]



3.0.441
=======

REQUEST.Reset() doesn't support the parameter anymore. To completely reset a REQEUST object, call REQUEST.ResetAll(). [606]



3.0.439
=======

AFP can now be activated via the internet from within the ControlCenter without having to retype all license information. [530]

New HTTP object. To obtain a reference, call SERVER.CreateObject("HTTP"). Currently, the only method is Get(cURL) which returns the contents of the specified URL. Only http:// URLs are supported. Typically, you would use this function when you want to download files from other servers or when you need to access an ASP, PHP, etc. file on the current server. [558]

New Method CConfig::RemoveValue(tcValue,tuRoot) removes a value from a configuration file. The value can be an attribute or a node. [596]



3.0.438
=======

Changed the way the cache is accessed. All access to the cache now goes through the new CACHE object. AFP now keeps multiple versions of the same file in the cache. Each time a source file changes, a new file is added to the cache. This avoids any problems with files being in use when they need to be recompiled. [577]

FIX: Compiling a single AFP document might produce dozens of TMP files. [583]



3.0.434
=======

Server.Execute(cFile) executes another AFP document and returns to the current one afterwards. This is similar to including a file using the *!<[INCLUDE:]> statement but happens at runtime and is therefore slower. The REQUEST object remains available to the called object. If you want to pass parameters to the second page, you can do this with form variables:

Request.Form("aNewVariable","the value")
Server.Execute("anotherPage.afp")

and in anotherPage.afp use

? Request.Form("aNewVariable") [357]

The new Session.HasBeenAbandoned() method returns .T. after you called Session.Abandon() and before a new session has been created. [552]

FIX: The hardware keys geenrated by the ControlCenter and the ones from the AFP engine do now match in all cases. If you get a evaluation message with this version, please run the activation process again by visiting http://www.afpages.com/activate.afp [558]

The new Session.PlainURL(cURL) method removes all session information from a URL. You would use this function if you need a bookmarkable URL or when you want to add a URL to a querystring parameter. [568]

An error inside an error handler hangs the AFP thread. This is a problem in VFP itself. If you run AFP using VFP 8, you gain extra stability. The error handler inside AFP and the two error events (afpa.code and afp.code files) are wrapped by TRY...CATCH blocks. If an error ocurred inside the error handler, a message is written to the event log and the error handling routine is cancelled. However, due to the error priorities in VFP 8, this error handler doesn't jump in when you have code in the Error event of your own objects. To cancel execution in your own error events, call SERVER.Throw(cError,nError). [570]



3.0.433
=======

The default for AFP is now to run in isolated mode, not in MTDLL mode. [546]



3.0.432
=======

When called without parameters, Session.URL() returns a link back to the current page. [482]

The C24 layer now includes the translation functionality. The LANGFILE.DBF must be located in the \AFP3\C24 directory. If it doesn't exist, a new and empty file is created automatically. To enable translation in your AFP application, you must activate it in your application.prg. The AFP.INI file settings are ignored. To activate translation, you may pick between the following two options. To use a fixed language or determine the language in your code, use

FOX.cLanguage = "en" && or whatever
FOX.lLocalize = .T.

if the language setting in the browser should determine which language present to the user, you can use the following two lines:

FOX.lAutoLocalize = .T.
FOX.lLocalize = .T. [499]

You can now customize the function that is used to convert any ?, ?? and = expression into a string. By default, AFP uses VFP's TRANSFORM function. If you want to use a different function, you can add a <build-option> tag to the .afpa file. This is from the C24_Fox.afpa file:

<application>
<build-option name="transform" command="=" function="TransformPlain"/>
<build-option name="transform" command="?" function="TransformPlain"/>
<build-option name="transform" command="??" function="TransformTranslate"/>
</application>

For instance, the following line in a .afp file

<%? "value"%>

is converted to

___AFPContent = ___AFPContent + TransformPlain("value")

in the resulting .prg file. You can use this to include your own translation function or to redefine the output operators "?", "??" and "=". [499]

The AFP service now does not allow for debug instances, anymore. If you set debug/afpengine to true, a warning is issued and the isolated mode used instead. [526]

When an error occurs, AFP tries to bring VFP into the foreground, before displaying the debug messagebox. On Windows 2000/XP/.NET Server this results in a flashing window. Previously, the debug messagebox were often missed because Windows displays it behind the browser window. [529]

The Voodoo PlugIn compiles the Voodoo.prg if needed. A missing Voodoo.prg is not reported into the event log. Instead, you notice this with a "VOODOO.PRG does not exist" error when you try to create the AFPPAGE object. [540]

If a plugin caused an error while loading, AFP still reports this as an error, but continues to load. Previously, AFP refused to launch for safety reasons. [540]

The session ID is now appended to the URL instead of inserted into the middle. [548]



3.0.431
=======

Windows XP and .NET Server need a different service. Please use AFP3Srv.NET.EXE instead of AFP3Srv.EXE. The XP service requires the Microsoft .NET Framework version 1.0 or higher. [413]

Server.Version() does now always return the version of AFP3Engine.DLL [497]

FIX: AFP Service caused permanent CPU usage [505]

The "cache FXP" option has been removed because it caused too much trouble. If you need more performance, consider using the DirectCall PlugIn [521]



3.0.427
=======

SERVER.Info() returns a complete HTML page that contains a summary of the current status, like various settings, file versions, etc. [442]

FIX: Session.Timeout(nValue) now works. The SESSION.DBF file must be deleted when installing build 427 because its format has changed [498]



3.0.426
=======

In the ControlCenter you can use the "new" button on the config form to create a new afp.config file with just the default values. [415]

The UNLOAD event (Procedure event:unload) is triggered in the application (*.afpa.code), if it is unloaded because it has to be recompiled. [424]

The %bin% directory has been removed since it's not needed anymore. [444]

When an error is encountered in AFP, the detailed error page now shows the exception log entry in addition to the "500 Internal Server" error message. [468]

In config/afp/session/timeout you can specify the initial session timeout in minutes. The default value is 30 minutes. [484]

Server.Throw("message") can be used to throw an exception. [491]

FIX: application PRG file is only compiled if one of the source files has changed [492]



3.0.425
=======

The recommend setting for debug/cache-fxp is false. This slightly reduces performance but makes it much easier to test afp application. If you need maximum performance, turn this setting on. [471]

FIX: All form variables and multipart data are cleared out on every request. Only when passing on to another page using Response.Call() or Server.Transfer(), form data remains available. [477]

The following server variables are now also supported. Please note that not every server must provide every variable in every situation.

CONTENT_TYPE
CONTENT_LENGTH
CERT_COOKIE
CERT_FLAGS
CERT_ISSUER
CERT_KEYSIZE
CERT_SECRETKEYSIZE
CERT_SERIALNUMBER
CERT_SERVER_ISSUER
CERT_SERVER_SUBJECT
CERT_SUBJECT
GATEWAY_INTERFACE
HTTPS
HTTPS_KEYSIZE
HTTPS_SECRETKEYSIZE
HTTPS_SERVER_ISSUER
HTTPS_SERVER_SUBJECT
LOGON_USER

To find out which variables are passed, use the following AFP code fragment:

<%? SERVER.HTMLEncode(REQUEST.cData)%> [478]

All AFP pages now have access to the built-in exception handling. Anywhere in an afp, afp.code and afpa.code file you can use these commands:

_BEGIN
_TRY
* Do something that might cause an error
_CATCH
* handle the error or report the exception like this
__EXCEPTION.Report()
_END

In order to raise an exception, you can use

_THROW "There's something wrong here"

Exception handling is implemented using #DEFINE statements that are inserted at the beginning of each compiled page. You can use them if you need exception handling for example in a plugin. [480]

AFP's host management has changed. AFP supports three host names. A host name is comprised of a top-level domain and a domain name. Network names like "localhost" or "MY_SERVER" are also considered to be host names. Subdomains are ignored. news.prolib.de and www.prolib.de would count as one host name. Host names are dynamically collected. Once the limit is reached, all further request to others hosts result in an HTTP 500 error. If for example, you entered:

http://localhost/index.afp
http://my_server/index.afp
http://www.prolib.de/index.afp

Any other host name will result in an error. The following would not work:

http://www.afpages.de/index.afp

even though prolib.de and afpages.de point to the same web server. However, the following does work:

http://shop.prolib.de/index.afp

since it's treated as the registered domain "prolib.de". To increase the number of host names you will be able to buy additional host licenses. Also, each legally independent web site needs a separate host license. If you host AFP pages for other companies or individuals, you MUST buy a host license for each company or individual. Please contact woody@prolib.de for details and pricing information (before you complain <g>). [481]

FIX: Session timeout is always measured in minutes [483]



3.0.424
=======

Form variables can now be changed. The syntax has been extended for this to

cOldValue = Request.Form("formvar","new value")

You can only change the first occurrence of a form variable name. That excludes multiple HTML form controls with the same name and controls that allow multiple selections. You cannot add new form variables. [434]

FIX: C24 application to change the current directory to the one in which the AFP file resides if the AFP engine runs in either the out-of-process host (AFP3Host.EXE) or in debug mode. You can activate the out-of-process host by setting config/afp/server/isolated to "YES". This behavior is closer to the original AFP 2.4 and the recommended setting for AFP 2.4 compatible applications. [436]

Changing Request.cQueryString does not automatically update the internal QueryString collection. You need to call Request.Reset() to achieve this. [437]

Request.Reset() now takes an optional parameter. If passed .T., it does use the existing cQueryString property as a source, and does not reload the QUERY_STRING parameter. This is the default setting when Response.Call() is used. [437]

Request.QueryString() does now offer all the same possibilities as Request.Form() [469]

Request.Form(nRow,nCol) and Request.QueryVariable(nRow,nCol) allow direct access to the array [470]



3.0.423
=======

FIX: Allparameter.afp know correctly handles the INI files. [254]

In the config file the config/afp/server/error setting determines the HTML file that is sent to the browser in case of an error. This file can contain textmerge expressions that are evaluated when an error ocurrs. There's no default value for this setting. Previous versions used the "HTTPError.html" file if it was found in the root directory. To continue using this file, you need to activate it explicitely. [364]

In the afp.config file you can set config/afp/debug/show-error to "YES" to always get a detailled error report, when an error occurs. This setting has presedence over any HTML error setting and is only evaluated when the AFP Engine starts up. If you need to make a case-by-case decision on whether you want to display an error message or not you can call the THIS.ShowError() method in a textmerge expression of your error HTML file that has been specified in config/afp/server/error. [403]

FIX: FOX.ReadINIVar() implemented. [429]



3.0.246
=======

FIX: ... WIDTH=100%> is now properly recognized as being part of the HTML portion. [428]


© 1999 - 2009  ProLib Software GmbH,   Webmaster
09/22/2006 by ProLib Software GmbH

 
[ Index ][ News ][ Description ][ Documentation ][ Demo pages ][ Weblinks ][ Download ][ Contact ][ imprint ][ e-Mail ]