images not loading in node application in IIS windows server - node.js

structure
->app.js
->public/images/banner.jpg
->index.html
index.html
<img style="width: 100%" alt="" src="/images/banner.png"/>
app.js
app.use(express.static(path.join(__dirname, '/public')));
its working fine in linux and in windows server with localhost. But not loading when opening with IIS
error - cannot get http://IP/images/banner.png
the alias name is "api"
I tried http://IP/api/images/banner.png its working fine.
So how to pass alias name with the ip from iis to nodejs?

Changes were required in outbound rules
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<system.webServer>
<rewrite>
<rules>
<rule name="ReverseProxyInboundRule1" stopProcessing="true">
<match url="(.*)" />
<action type="Rewrite" url="http://localhost:3000/{R:1}" />
</rule>
</rules>
<outboundRules>
<rule name="testing2" preCondition="IsHTML" stopProcessing="true">
<match filterByTags="Img, Link, Script" pattern="(.*)(images|styles|scripts)(.*)" />
<action type="Rewrite" value="{R:1}api/{R:2}{R:3}" />
</rule>
<preConditions>
<preCondition name="IsHTML">
<add input="{RESPONSE_CONTENT_TYPE}" pattern="^text/html" />
</preCondition>
</preConditions>
</outboundRules>
</rewrite>
</system.webServer>
</configuration>

Related

IIS rewrite: Outbound rewrite rules cannot be applied when the content of the http response is encoded ("identity")

I've set up an IIS reverse proxy to serve some content from within WSL with the following web.config:
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<system.webServer>
<rewrite>
<rules>
<rule name="ReverseProxyInboundRule1" stopProcessing="true">
<match url="(.*)" />
<action type="Rewrite" url="http://localhost:6006/{R:1}" />
<serverVariables>
<set name="HTTP_X_ORIGINAL_ACCEPT_ENCODING" value="{HTTP_ACCEPT_ENCODING}" />
<set name="HTTP_ACCEPT_ENCODING" value="" />
</serverVariables>
</rule>
</rules>
<outboundRules>
<rule name="ReverseProxyOutboundRule1" preCondition="ResponseIsHtml1">
<match filterByTags="A, Form, Img" pattern="^http(s)?://localhost:6006/(.*)" />
<action type="Rewrite" value="http{R:1}://iansdesktop/{R:2}" />
</rule>
<preConditions>
<preCondition name="ResponseIsHtml1">
<add input="{RESPONSE_CONTENT_TYPE}" pattern="^text/html" />
</preCondition>
</preConditions>
</outboundRules>
</rewrite>
</system.webServer>
</configuration>
However this results in a 500.52 error complaining that the response is encoded (it isn't encoded, I've verified with telnet) and the encoding reported is "identity" which apparently means no encoding at all.
How can I change my rules to fix this?

iis rewrite virtual subfolder path

I try change the subfolder path (virtual directory) via rewrite module on IIS
I want change the url path from "www.site.com/photos/20/be2f-8ed24a0d1a9a.jpg" to "www.site.com/photos/20_new/be2f-8ed24a0d1a9a.jpg" where "/photos" is virtual directory and "/20" its subfolder
I write rule:
<rewrite>
<rules>
<clear/>
<rule name="photo path rewrite" stopProcessing="true">
<match url="(.*)" />
<conditions>
<add input="{QUERY_STRING}" pattern="/photos/20/(.*)" />
</conditions>
<action type="Redirect" url="{HTTP_HOST}/photos/20_new/{C:1}" redirectType="Temporary" />
</rule>
</rules>
<rewriteMaps></rewriteMaps>
</rewrite>
What I doing wrong? Thanks:)
Could you explain the URL you want to redirect belong to src attribute or you just want to access the URL directly?
If URL is accessed directly, you just need to change your condition input from {QUERY_STRING} to {REQUEST_URI}.
If this url belong to "src" attribute in the html img tag , then you can try this outbound rule.
<rewrite>
<outboundRules>
<rule name="outbound rule" preCondition="IsImage">
<match filterByTags="Img" pattern="(.*)" />
<conditions>
<add input="{REQUEST_URI}" pattern="/photos/20/(.*)" />
</conditions>
<action type="Rewrite" value="{HTTP_HOST}/photos/20_new/{C:1}" />
</rule>
<preConditions>
<preCondition name="IsImage">
<add input="{RESPONSE_CONTENT_TYPE}" pattern="^text/html" />
</preCondition>
</preConditions>
</outboundRules>
</rewrite>

HTTP 401 Error Only When Using IIS ARR Proxy

A application which contains a web interface is running on a Windows Server 2019 system with IIS 10 and ARR installed. When navigating to the webpage using IP:Port the webpage loads correctly. When navigating to the webpage using domain.com the website has some content that shows a 401 error in the console, and page does not load correctly.
When navigating to the domain the request passes through IIS and URL Rewrite. It would seem that there is some issue in regards to passing the information through the proxy.
This is the code for the rewrite rule in IIS:
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<system.webServer>
<rewrite>
<rules>
<rule name="ReverseProxyInboundRule1" stopProcessing="true">
<match url="(.*)" />
<action type="Rewrite" url="http://localhost:33337/{R:1}" />
<serverVariables>
<set name="HTTP_ACCEPT_ENCODING" value="" />
</serverVariables>
</rule>
</rules>
<outboundRules>
<rule name="ReverseProxyOutboundRule1" preCondition="ResponseIsHtml1">
<match filterByTags="A, Form, Img" pattern="^http(s)?://localhost:33337\/?(.*)" />
<action type="Rewrite" value="http{R:1}://sub.domain.com/{R:2}" />
</rule>
<preConditions>
<preCondition name="ResponseIsHtml1">
<add input="{RESPONSE_CONTENT_TYPE}" pattern="^text/html" />
</preCondition>
</preConditions>
</outboundRules>
</rewrite>
<urlCompression doStaticCompression="false" doDynamicCompression="true" dynamicCompressionBeforeCache="false" />
</system.webServer>
</configuration>
This is the GitHub Issue link for this specific issue:
https://github.com/qbittorrent/qBittorrent/issues/11207
I reproduced the issue.
Apparently qBittorrent expecting clients to send same-origin Referer headers. In your case it must be localhost:33337 but obviously sub.domain.com is being sent.
This security measure is activated by Enable Cross-Site Request Forgery (CSRF) protection setting that can be reached via qBitorrent > Options > Web UI > Security.
You have two options for the solution.
Disable the setting.
Rewrite the Referer header with an appropriate value.
If you want to rewrite the header, after allowing server variables HTTP_REFERER and HTTP_ORIGIN as you did for HTTP_ACCEPT_ENCODING, you should change your rules as follows.
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<system.webServer>
<rewrite>
<rules>
<rule name="ReverseProxyInboundRule1" stopProcessing="true">
<match url="(.*)" />
<action type="Rewrite" url="http://localhost:33337/{R:1}" />
<!-- New Optional Condition -->
<conditions logicalGrouping="MatchAny">
<add input="{HTTP_REFERER}" pattern="^(?:https?://[^/]*/(.*))?$" />
</conditions>
<serverVariables>
<set name="HTTP_ACCEPT_ENCODING" value="" />
<!-- New Header Rewrite -->
<set name="HTTP_REFERER" value="http://localhost:33337/{C:1}" />
<!-- Remove Origin Header -->
<set name="HTTP_ORIGIN" value="" />
</serverVariables>
</rule>
</rules>
<outboundRules>
<rule name="ReverseProxyOutboundRule1" preCondition="ResponseIsHtml1">
<match filterByTags="A, Form, Img" pattern="^http(s)?://localhost:33337\/?(.*)" />
<action type="Rewrite" value="http{R:1}://sub.domain.com/{R:2}" />
</rule>
<preConditions>
<preCondition name="ResponseIsHtml1">
<add input="{RESPONSE_CONTENT_TYPE}" pattern="^text/html" />
</preCondition>
</preConditions>
</outboundRules>
</rewrite>
<urlCompression doStaticCompression="false" doDynamicCompression="true" dynamicCompressionBeforeCache="false" />
</system.webServer>
</configuration>
BTW bear in mind that, qBittorrent warns you about the issue. Remember to check Execution Log tab.

URL rewriting of subdirectory to diffent port using IIS

I'm trying to integrate ASP.net and Node.js on a single server.
ASP.net is at localhost:8080
NodeJs is at localhost:4000
My expectation is here.
client ----> IIS Server ----> ASP.NET (no rewriting except /api/* localhost:80)
(rev.0970.co.kr) |---> Node.js (matching with /api/* localhost:4000)
Node app is executed as a windows service, and serve localhost:4000/api/ locally. And should be accessed with http://rev.0970.co.kr/api/signin
All request excepting /api/ should be served normal IIS asp.net. (ex. http://rev.0970.co.kr/index.aspx)
My Setting Steps
- install ARR and UrlRewrite module
- enable proxy of ARR
- add rule to urlrewrite section as below.
<rule name="Proxy">
<match url="api/(.*)"/>
<conditions>
<add input="{HTTP_HOST}" pattern="rev.0970.co.kr" />
</conditions>
<action type="Rewrite" url="http://localhost:4000/api/{R:1}" />
</rule>
Result
- http://rev.0970.co.kr/api/signin : success
- http://rev.0970.co.kr/index.aspx : fail - 404 not found
I thought http://rev.0970.co.kr/index.aspx did not match api/(.*), so IIS might render index.aspx.
When I removed whole rule settings of urlrewrite, http://rev.0970.co.kr/index.aspx worked.
What did I do wrong?
edit
Here is my full web.config file.
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<system.webServer>
<rewrite>
<outboundRules>
<rule name="ReverseProxyOutboundRule1" preCondition="ResponseIsHtml1">
<match filterByTags="A, Form, Img" pattern="^http(s)?://localhost:4000/(.*)" />
<action type="Rewrite" value="http{R:1}://rev.0970.co.kr/{R:2}" />
</rule>
<preConditions>
<preCondition name="ResponseIsHtml1">
<add input="{RESPONSE_CONTENT_TYPE}" pattern="^text/html" />
</preCondition>
</preConditions>
</outboundRules>
<rules>
<rule name="Proxy">
<match url="api/(.*)" />
<conditions>
<add input="{HTTP_HOST}" pattern="rev.0970.co.kr" />
</conditions>
<action type="Rewrite" url="http://localhost:4000/api/{R:1}" />
</rule>
</rules>
</rewrite>
<tracing>
<traceFailedRequests>
<add path="*">
<traceAreas>
<add provider="ASP" verbosity="Verbose" />
<add provider="ASPNET" areas="Infrastructure,Module,Page,AppServices" verbosity="Verbose" />
<add provider="ISAPI Extension" verbosity="Verbose" />
<add provider="WWW Server" areas="Security,CGI,RequestNotifications,Module,FastCGI" verbosity="General" />
</traceAreas>
<failureDefinitions timeTaken="00:00:00" statusCodes="404" />
</add>
</traceFailedRequests>
</tracing>
</system.webServer>
</configuration>

Reverse proxy with IIS

I'm trying to integrate ASP.net and Node.js on a server.
My expectation is here.
client ----> IIS Server ----> ASP.NET (except /api/. localhost:80)
(test.foo.com) |---> Node.js (starting with /api/. localhost:4000)
Node app is executed as a windows service, and serve localhost:4000/api/ in locally. And should be accessed with http://test.foo.com/api/signin
All request excepting /api/ should be served normal IIS asp.net. (ex. http://test.foo.com/index.aspx)
My trial:
- Installed urlrewrite module and application request routing cache module.
- Added rewriting rule as below
pattern: /api/(.*)
URL rewrite : http://localhost:4000/api/{R:1}
My result:
- http://test.foo.com/api/signin returned as 503 Service Unavaile
Question:
- Using URLrewrite is the right solution for my case?
Append
I tried to with 127.0.0.1 instead localhost with below web.config setting.
That result was same "503".
<rewrite>
<rules>
<rule name="ReverseProxyInboundRule1" stopProcessing="true">
<match url="/api/(.*)" />
<action type="Rewrite" url="http://127.0.0.1:4000/api/{R:1}" />
</rule>
</rules>
<outboundRules>
<rule name="ReverseProxyOutboundRule1" preCondition="ResponseIsHtml1">
<match filterByTags="A, Form, Img" pattern="^http(s)?://127.0.0.1/(.*)" />
<action type="Rewrite" value="http{R:1}://127.0.0.1:4000/{R:2}" />
</rule>
<preConditions>
<preCondition name="ResponseIsHtml1">
<add input="{RESPONSE_CONTENT_TYPE}" pattern="^text/html" />
</preCondition>
</preConditions>
</outboundRules>
</rewrite>
Append again
Instead loop adapter, change to ipv4 address. And tried to access anther PC. But result was same.
<rewrite>
<rules>
<rule name="ReverseProxyInboundRule1" stopProcessing="true">
<match url="(.*)" />
<action type="Rewrite" url="http://192.168.123.12:4000/api/{R:1}" />
</rule>
</rules>
<outboundRules>
<rule name="ReverseProxyOutboundRule1" preCondition="ResponseIsHtml1">
<match filterByTags="A, Form, Img" pattern="^http(s)?://192.168.123.12:4000/api/(.*)" />
<action type="Rewrite" value="http{R:1}://192.168.123.12/{R:2}" />
</rule>
<preConditions>
<preCondition name="ResponseIsHtml1">
<add input="{RESPONSE_CONTENT_TYPE}" pattern="^text/html" />
</preCondition>
</preConditions>
</outboundRules>
</rewrite>

Resources