Project

General

Profile

Using WResource with ISAPI

Added by Mario Diethelm over 1 year ago

Hi,

I have an application that uses a WResource to redirect the user to other services in the Web. The applications works fine with the built in httpd connector, but when I try to use it under IIS with the ISAP connector, the WResource handleRequest is never called, never gets activated (I am using a WPushButton connected to a WLink that targets the WResource to a new Window to active the WResource).

Any suggestions?

Thanks a lot.


Replies (17)

RE: Using WResource with ISAPI - Added by Roel Standaert over 1 year ago

I'm always surprised when anyone still uses wtisapi or wtfcgi. Is there any reason why you actually have to use ISAPI?

I can't immediately think of a reason why your WResource wouldn't work, though. If you build the widget gallery example, does downloading a resource from the widget gallery (under Media -> Resources) work?

RE: Using WResource with ISAPI - Added by Mario Diethelm over 1 year ago

Hi Roel, thanks for your feedback.

I am using IIS mainly for two reasons: 1. IIS allows to isolate the application from stuff like http vs https traffic handle, URL redirections when your site is under maintenance and other similar events and 2. because in my experience applications under IIS run between 10% to 15% faster than using the httpd connector (I have executed tests using MySQL and SQL Server with the same results).

Having said that, based on your suggestion, instead of downloading and building the widget gallery example, I wrote a very simple Wt application that ask for an URL to switch to and uses a WResource, linked to a WPushButton, to actually execute the switch using HTML code streamed to the WResource's handleRequest function member "response" parameter.

The results are the same that I previously commented. With the httpd connector everything works fine. With the isapi connector the WResource's handleRequest is never activated (I added several Wt::log calls inside the WResource's handleRequest function member: at the beginning, at the end and in a couple of specific points. With the httpd connector all those track records are showed in the log file, but with the isapi connector none of those track records even appears). With the isapi connector the result of activating the WResource clicking the WPushButton is an "Error HTTP 404.0 - Not Found" page issued by IIS (IIS informs that the requested URL corresponds to the Wt application deploy URL plus the WResource's assigned internal path plus ?wtd).

I am using Visual Studio C++ 2019, Wt 4.8.2 under Windows (my development machine is a Windows 11 machine, same results under Windows 2016 server). I am going to try with the widget gallery but it seems to me that I am going to get the same results. I would appreciate if you could help me with any new suggestions.

Best regards.

RE: Using WResource with ISAPI - Added by Wim Dumon over 1 year ago

Hello Mario,

I don't remember having seen any problems related to WResource in the ISAPI connector. What strikes me as weird in your description, is that you get an IIS-generated 404 rather than a Wt generated 404. This may indicate that the routing of the requests is not correctly configured in IIS. All requests for the application URL, including all sub-URLs, should be routed to the application. Could you verify if there's some IIS setting that may affect this?

Best regards,
Wim.

RE: Using WResource with ISAPI - Added by Mario Diethelm over 1 year ago

Hello Wim, thanks for you answer.

I agree with you about the root cause of this behavior. In some way IIS is catching and directly processing the http request instead of route it to the application. I have been trying to identify an IIS setting that may affect this without success until now. In the mean time I did some tweaks in my Wt "simple" application. The Http 404 error was caused because I configured an internal path (setInternalPath) for the WResource that pointed to nothing. Once I created an html file with the same name of the internal path, located in the application root directory, instead of the 404 error I started to get the html page. In fact if I do not configure the internal path, I get the application root directory.

I will keep trying to identify the IIS configuration issue. Thanks again.

Best regards.

Mario.

RE: Using WResource with ISAPI - Added by Mario Diethelm over 1 year ago

Hello again.

I keep trying to figure out what is going wrong under IIS with WResource widget. The last test that I did was try to build a PDF file using a WResource, with the same results: the WResource handleRequest function member is never activated and IIS answer with a 404 error (the requested URL is the name of the PDF file inserted as a kind of internal path in base application URL).

I do not remember having seen this weird behavior with Wt 3.7.1 (I switch to Wt 4.8.2 just some months ago from Wt 3.7.1), so I am going to download Wt 3.7 and re build my test program with Wt 3.7 version just to check.

I will keep you posted. Best regards.

RE: Using WResource with ISAPI - Added by Mario Diethelm over 1 year ago

Hello Wim, Roel,

As I commented in my previous post, I downloaded Wt 3.7 and re built my test program. Everything works perfect with both httpd connector and ISAPI connector (same machine, same IIS configuration). I guess that something have changed in the Wt 4.8.2 (or some previous Wt 4.x version) that is generating the unexpected behavior that I reported previously.

I look forward hearing from you. Thanks a lot.

Best regards.

RE: Using WResource with ISAPI - Added by Wim Dumon over 1 year ago

Mario,

That's weird. What is the exact url of the resource and what is the exact URL of the application?

Wim.

RE: Using WResource with ISAPI - Added by Mario Diethelm over 1 year ago

Hello Wim.

For all the tests cases I deploy the application at the URL localhost:8080/wresourceTest for httpd connector and localhost/resourceTest for the ISAPI connector (resourceTest is an IIS virtual directory). I am not using a specific URL for the WResource. As far as I understand it is generated by the library (Wt).

I have attached both the Wt-4.8-2 and the Wt-3.7 versions of the application. The application just asks for an URL (let say http://www.mysql.com or http://www.boost.org, you name it) through a WLineEdit widget, loads this value in a WResource data member using a WPushButton and then executes the page switch through a WPushButton linked to the WResource that actually streams some html code to the WResource's handleRequest function member Http::Response parameter to execute the jump or switch, in a new browser tab, to the URL entered by the user. As I commented in my previous posts, the application works fine with the httpd connector for both 4.8.2 and 3.7 versions and with the ISAPI connector for the 3.7 version but do something different for the 4.8.2 version with the ISAPI connector (it actually shows the application base page - localhost/resourceTest - in the new tab).

The source files included in each of the two versions are: wResourceTest.cpp (main program, WRun call + createWebApplication routine), wresourcepage.cpp (implements the widget to ask for the URL to jump to with some buttons), wresourcepage.h, wresourceobject.cpp (implements the resource to jump to another web page, a WResource derived class), wresourceobject.h. All built and tested in a Windows 11 machine with Visual Studio C++ 2019.

Hope this could help. Again, thanks a lot.

Best regards.

Mario.

RE: Using WResource with ISAPI - Added by Mario Diethelm over 1 year ago

Hello again,

Just to try to re cap the case and because I am really stuck with this issue, I would like to ask for any recommendations that could help me to solve this problem:

  • Based on the examples that I sent in my previous post, I think that actually there is some issue when I am using WResource under Wt-4.8.2 linked with the ISAPI connector
  • As I commented in my previous post the same program runs in the expected way under Wt-3.7 linked with the ISAPI connector: the WResource's handleRequest routine is executed every time that you activate the WResource
  • In the case of the Wt-4.8.2 library with the ISAPI connector, the WResource's handleRequest routine is never executed when you activate the WResource
  • Both versions, Wt-3.7 and Wt-4.8.2, linked with the httpd connector actually execute the WResource's handleRequest routine every time that you activate the WResource
  • This behavior is exactly the same for different types of WResource (a web page switching as in the above commented example or a PDF rendering starting from a text file)
  • All the tests that I did were executed using exactly the same machine, with exactly the same IIS configuration. I use the same memory models (/MD) to compile all the C++ sources. All the binaries (.exe, .dll) are built for x64

Did you have the chance to review the examples that I sent in my previous post? Am I coding something wrong? Is it possible that some specific configuration in IIS could make the difference between the two Wt versions? If you do not see any problem, could you suggest me a different way to implement a WResource?

Thanks again.

Best regards.

RE: Using WResource with ISAPI - Added by Mario Diethelm about 1 year ago

Hello,

trying to figure out how to solve the already commented problem, I did some little research inside the Wt library, based on the same example program that I shared in a previous post. Some comments follow:

  • I started downloading and building the last Wt library version (4.9.2). Then of course I re built the test program with this very last version
  • Same results as before. It works fine with the httpd connector but it never calls the WResource's handleRequest function member using the ISAPI connector
  • I debugged the httpd connector version to realize the call sequence to handle a WResource
  • I added some flags (Wt:log messages) to WApplication.c, WSession.c, WController.c and WResource.c trying to determine where the difference between the two versions (httpd connector and ISAPI connector) actually happens
  • Starting from the WResource activation (click on the button that it is associated to the WResource through a WLink), the stack calls for the httpd connector is:
    1. WebController.c WebSession::Handler,
    2. WebSession.c WebSession::handleRequest
    3. WApplication.c WApplication::notify
    4. WebSession.c WebSession::notify
    5. WResource.c WResource::handle
    6. wresourceobject.c WebResourceWidget::handleRequest (WebResourceWidget is a derived class from WResource in the test program)

In the case of the ISAPI connector the sequence ends in step 3. The WApplication::notify is executed but WebSession::notify and the subsequent functions calls are never executed.

Hope this could help. Again, thanks a lot.

Best regards.

Mario.

RE: Using WResource with ISAPI - Added by Roel Standaert about 1 year ago

The only code in WApplication::notify is session_->notify(e). Are you suggesting that that's a null dereference, or a dangling pointer?

RE: Using WResource with ISAPI - Added by Mario Diethelm about 1 year ago

Hello Roel,

no, I am not suggesting that. If the session_ pointer were referencing null or any other invalid memory location probably an exception would be trigger, but the program continues running normally. What I actually thing is, for some reason that I am not able to figure out yet, that the call session_->notify(e) is catch by IIS instead of following the same flow that it does with the httpd connector.

By the way, in my previous post I said that I downloaded the Wt 4.9.2 library. Of course it is actually the Wt 4.9.1 version.

Best regards.

Mario.

RE: Using WResource with ISAPI - Added by Mario Diethelm about 1 year ago

Hello,

any comments or feedback?

Thanks. Best regards.

Mario

RE: Using WResource with ISAPI - Added by Mario Diethelm about 1 year ago

Hello again.

I would appreciate if you could comment if there is any chance to review or suggest any other feedback regarding this case.

Thanks a lot. Best regards.

Mario.

RE: Using WResource with ISAPI - Added by Mario Diethelm about 1 year ago

Hello,

doing a deeper analysis on the WResource activation call stack, I found some facts that I hope could help to figure out what I am doing wrong:

  1. The WebSession::notify routine is always executed. In my previous post I said that this routine was not executed but actually it is (sorry about that)
  2. The WResource::handle routine is not executed and consequently the WResource::handleRequest specialized version neither
  3. This is because the resource value parameter (loaded into the requestE local string variable) of the request message (obtained from event.impl_.handler.request() where event is the WebSession::notify parameter) does not contain the value "resource" (using the httpd connector version, when you activate the WPushButton that is assocaited to the WResource through a WLink, the resource value parameter contains "resource". Using the ISAPI connector the resource value parameter contains "jsupdate"
  4. WebSession::notify code starting on line 2438 is not executed because the local variable resource is set to nullptr (WResource *resource = nullptr; is declared in line 2420 and not value is assigned before line 2438) and requestE value is "jsupdate", so the logical value for (resource || (requestE && *requestE == "resource" && resourceE)) is false (resourceE is also nullptr because the value "resource" is not present int the request message).
  5. I tracked back the call stack and found that WebController::handleRequest sets all those values, specifically with a call to cgi.parse routine. Until now I am not able to establish why using the httpd connector this specific value is set to "resource" but using the ISAPI connector the value is set to "jsupdate"

As I commented before, all the tests are done using the same Windows 11 machine, with the same IIS server version. I am using Wt-4.9.1 and all code has been built using Visual Studio C++ 2019 for x64 (code built with ISO C++ 17 standard) . Again, hope this could be helpful, thanks a lot.

Best regards.

Mario.

RE: Using WResource with ISAPI - Added by Roel Standaert about 1 year ago

There does appear to be some regression in the routing when using ISAPI, I created issue #11348 to track progress on the fix.

RE: Using WResource with ISAPI - Added by Mario Diethelm about 1 year ago

Thanks Roel.

Best regards,
Mario

    (1-17/17)