We have just moved to a new dedicated server that has Windows 2008 and SQL Server 2008. I am trying to access an ASP page on the same server using Server.CreateObject("MSXML2.ServerXMLHTTP").
On our previous 2003 server this worked correctly, however with the new 2008 server the operation just times out.
Here is the code:
strURL = "http://www.storeboard.com/profile/profile_view.asp?MemberID=" & MemberID & "&sid=" & cSession.SessionID
Set oXMLHttp = Server.CreateObject("MSXML2.ServerXMLHTTP")
oXMLHttp.open "GET", strURL, false
oXMLHttp.send()
IF oXMLHttp.status = 200 THEN
strOut = oXMLHttp.responseText
ELSE
strOut = "Could not get XML data."
END IF
Set oXMLHttp = nothing
The code is very simple but I get the following error:
msxml3.dll error '80072ee2'
The operation timed out
/handle404.asp, line 291
Line 291 refers to oXMLHttp.Send() line.
Is there an alternative code I can use? I use the script other places on the server that access files on other servers and they work correctly, but any access to files on our server doesn't work.
Is there an alternative method that will allow me to keep the URL intact in the browser? The person could write the URL in their browser: http://www.example.com/hello the file doesn't exist but I have a 404 handler that then points the user to the correct path without changing the browser URL which is essential for our SEO ratings.
Microsoft has a published a KB article entitled INFO: Do Not Send ServerXMLHTTP or WinHTTP Requests to the Same Server
If the ServerXMLHTTP or WinHTTP component must send a request to
another ASP on the same server, the target ASP must be located in a
different virtual directory and set to run in high isolation. Avoid
using ServerXMLHTTP or WinHTTP to send a request to an ASP that is
located in the same virtual directory.
...
A finite number of worker threads (in the Inetinfo.exe or Dllhost.exe
process) is available to execute ASP pages. If all of the ASP worker
threads send HTTP requests back to the same Inetinfo.exe or
Dllhost.exe process on the server from which the requests are sent,
the Inetinfo.exe or Dllhost.exe process may deadlock or stop
responding (hang), because the pool of worker threads to process the
incoming requests will be exhausted. This is by design.
As far as alternatives go, it depends on what you're doing with the response after you receive it. If the entire purpose of the script is to forward the request to profile_view.asp, you might be able to use Server.Transfer instead.
I had this same issue. In my case the web request I was trying to make was an internal site url (within the same app pool). With server side debugging set to enabled, the asp app pool seems to be restricted to a single worker thread. By disabling this feature, the request was then able to be processed.
msxml3.dll is pretty old. It was distributed with Internet Explorer 6 to give you a rough idea.
Can you have someone install a later version on the server?
http://support.microsoft.com/kb/269238 gives you a list of versions to send to whoever it responsible for the server.
If the problem is genuinely down to a time out you could look into switching ASP buffering off. (This based soley on a guess that if the server object started to receive a response it would hold off on the timeout front.
Alternatively you coudl try processing the value on the client side, below is a function from some code I wrote which does this....
function getDets(RateID) {
var xmlHttp;
try {
xmlHttp=new XMLHttpRequest(); // Firefox, Opera 8.0+, Safari
}
catch (e) {
try {
// Internet Explorer
xmlHttp=new ActiveXObject("Msxml2.XMLHTTP");
}
catch (e) {
try {
xmlHttp=new ActiveXObject("Microsoft.XMLHTTP");
}
catch (e) {
alert("Your browser does not support AJAX!");
return false;
}
}
}
xmlHttp.onreadystatechange=function()
{
if(xmlHttp.readyState==4) {
var str;
var newStr;
str=xmlHttp.responseText
newStr=str.split("|");
window.document.all.OR2.style.display="block";
window.document.all.OR3.style.display="block";
window.document.OvertimeRates.Description.value=newStr[0];
window.document.OvertimeRates.Factor.value=newStr[1];
}
}
if (RateID==0) {
window.document.OvertimeRates.Description.value="";
window.document.OvertimeRates.Factor.value="";
}
else {
xmlHttp.open("GET","GetOvertimeRate.asp?RateID="+RateID,true);
xmlHttp.send(null);
}
}
Good luck!
Related
We build and deploy our web application to our dev environment automatically every night (using VSTS). When we come into the office in the morning, the first person to access the application has to wait an extended period for each page to load the first time. Subsequent loads are very fast.
The problem has a greater impact in our live environment where, after a deployment, it is potentially an end-user who is the first person to access the application and complain of slowness. To mitigate for this, a member of the team is currently accessing every page of the application manually after deployment to the live environment so that they 'pre-load' every page, which works, but is obviously time-consuming!
I've done a fair bit of searching on the subject, and have configured the appropriate Application Pool in our IIS server (IIS 8.5) so that its Start Mode is set to "AlwaysRunning". I've also edited our applicationHost file and set the appropriate Sites with the preloadEnabled="true" attribute. I did this after reading the instructions in this very helpful Microsoft documentation.
However, if I'm reading that documentation correctly, any pre-loading of the website which might alleviate the issue we're having (and I'm not even certain that this is the kind of pre-loading that I'm thinking of) only takes place when the server, the IIS service of the Application Pool are restarted. This isn't happening in our case. We need the pre-loading to take place following a deployment of the application to the IIS server.
Is there a way to automate this pre-loading?
One way of doing this would be to perform a HTTP request automatically:
As soon as the app was deployed (by running a task from the deploying machine)
Before the application pool has the chance to shut itself down (using Task Scheduler for instance)
Personally, I use a tool that is run in both cases to keep the site warmed up.
Advantages
Robust control over how and when this warm-up is executed.
It's completely independent from any IIS or web.config setup.
Disadvantages
Generates "bogus" log information.
Keeps the app permanently in memory (the Pool would never time-out, essentially wasting server resources for sites with a low # of visitors).
Sample
Such a tool could be a simple console app written as follows:
var taskInfo = new {
Url = "http://www.a-website-to-keep-warm.url",
UseHostHeader = true,
HostHeader = "www.a-website-to-keep-warm.url",
HttpMethod = "head"
};
HttpStatusCode statusCode = HttpStatusCode.Unused;
long contentLength = 0;
try
{
Dictionary<string, string> headers = new Dictionary<string, string>();
HttpWebRequest webRequest = (HttpWebRequest)WebRequest.Create(taskInfo.Url);
webRequest.Method = taskInfo.HttpMethod.ToUpper();
if(taskInfo.UseHostHeader)
webRequest.Host = taskInfo.HostHeader;
using (HttpWebResponse webResponse = (HttpWebResponse)webRequest.GetResponse())
{
//did we warm-up the site successfully?
statusCode = webResponse.StatusCode;
contentLength = webResponse.ContentLength;
//optionally read response headers
foreach (string header in webResponse.Headers)
{
headers.Add(header, webResponse.Headers[header]);
}
}
decimal kilobytes = Math.Round(contentLength / 1024M, 1);
Debug.WriteLine($"Got {kilobytes:F1} kB with statuscode: \"{statusCode} \" ...");
}
catch (Exception ex)
{
Debug.WriteLine($"taskInfo failed with exception: {ex.Message}");
}
In my case, I read a bunch of taskInfo objects from a json file and execute them asynchronously every X minutes, making sure X is lower than the Pool-timeout value. It is also run immediately after every deploy.
Because we're not interested in getting the entire content, it uses a HTTP HEAD request instead of GET. Lastly, it supports multiple sites on the same host by adding a Host header to the request.
I'm trying to do low latency data pushing from the server to the client with HTTP.
I'm using ASP.NET Web API and I have this in my controller:
var response = HttpContext.Current.Response;
for (int i = 0; i < 10; i++)
{
response.BinaryWrite(Encoding.UTF8.GetBytes(i.ToString()));
response.Flush();
Thread.Sleep(200);
}
This should send the numbers 0 to 9 to the client every 200 milliseconds but it adds an error message to the stream saying that "Server cannot set status after HTTP headers have been sent." I's not even an exception I can catch... i'ts just writing error page HTML to the response stream....
In this example I'm not even using any custom headers... It doesn't make any sense. I got it to work somehow while trying different things, but when I deployed it to staging I got the same behavior the difference is that the staging server runs it on Ubuntu with Mono and Apache instead of IIS on Windows with regular .NET.
I'm looking for an explanation of why it does this more than a fix...
I'm having an odd, sporadic problem with a simple test app (Visual Studio console application) that acts as a watchdog for a hosted aspx web site (not app) by sending it simple http requests and timing the response times. I've used this for many weeks in the past without this particular problem. At seemingly random times during the day, my http requests start failing with the above error. They appear to be timeouts since the requests that fail are all taking 60 seconds. After a period of consistent errors as per above (random time periods from a few minutes to 90 minutes in one case) the errros stop and http responses start coming back with no errors at the normal speed (usually about .25s). The watchdog client requests triggers a very simple database lookup, just 1-2 lines of code on the server side. This is hosted at a shared windows hosting web host.
I can also trigger this behavior at will by updating any .cs file on my host site, which, among other things, causes the app pool to recycle. Immediately my watchdog app starts timing out again with the above error.
It smells like some kind of recycled connection problem, since if I simply restart the watchdog app, it works fine and responses start coming back at the normal delay.
I've tried setting request.KeepAlive = false and request.ServicePoint.ConnectionLimit = 1, those did not help.
Another clue, I cannot connect with IIS manager to either of two different websites hosted on this server, which has always worked fine. I'm getting "The underlying connection was closed" trying to connect via IIS Manager. Every time. I have not updated either of the sites in a while, so it wasn't any change of mine.
This is an asp.net 4 website on the backend running on IIS7 with a dedicated app pool in integrated pipeline mode.
Also if I change the sleeptime variable in the watchdog app to something like 30 seconds, the problem doesn't show up. There's some magic number in the range of I believe 10-20 seconds where if the requests are pausing more than that, they never fail.
I think the fact that IIS Manager can't connect is good evidence that something is wrong on the host side independant of my test app but I wanted to cover my bases before opening a support incident... especially since a simple restart of my console app fixes the problem... at least for a while.
class Program
{
//make a simple web request and just return the status code
static string SendHttpMsg(string url, string postData)
{
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(new Uri(url));
request.Method = "POST";
request.ContentType = "application/x-www-form-urlencoded";
ASCIIEncoding encoding = new ASCIIEncoding();
byte[] byte1 = encoding.GetBytes(postData);
request.ContentLength = byte1.Length;
//request.KeepAlive = false; //no effect
//request.ServicePoint.ConnectionLimit = 1; //no effect
Stream requestStream = request.GetRequestStream();
requestStream.Write(byte1, 0, byte1.Length);
requestStream.Close();
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
response.Close();
return ((int)response.StatusCode).ToString();
}
static void Main(string[] args)
{
int sleeptime = 5000;
string result = "";
while (true)
{
DateTime start = DateTime.Now;
try
{
//this is a very simple call that results in a very simple, fast query in the database
result = SendHttpMsg("http://example.com/somepage.aspx", "command=test");
}
catch (Exception ex)
{
//fancy exception handling here, removed
}
DateTime end = DateTime.Now;
TimeSpan calltime = end - start;
Console.WriteLine(end.ToString() + ", " + calltime.TotalSeconds.ToString("F") + " seconds " + result);
Thread.Sleep(sleeptime);
}
}
}
You could have dangling connections, and in HTTP 1.1 you are limited to 2 connections.
Try changing the HTTP Protocol Version used in the request:
request.ProtocolVersion = HttpVersion.Version10;
If that doesn't work, it could be taking a long time to resolve the proxy settings, which can be fixed by disabling the proxy settings in your application by adding the following to the .config file:
<system.net>
<defaultProxy enabled="false">
<proxy/>
<bypasslist/>
<module/>
</defaultProxy>
</system.net>
If either of the above fixes the problem, I'd recommend adding a try...catch...finally block around your request code, to ensure that each request is properly closed and disposed of (try setting request = null in your finally statement inside the method).
JS method
$.post('http://localhost:21067/HandlerServices/Product/ProductHandler.ashx', 'action=productlist', function (data) { console.log(data); console.log('hi') });
This ashx code is working but i recive nothing in response
This is ashx.cs code
context.Response.ContentType = "text/plain";
if (!string.IsNullOrEmpty(context.Request.QueryString["action"]))
{
string action = context.Request.QueryString["action"];
switch (action.ToLower())
{
case "productlist":
context.Response.Write("ersoy");
break;
}
}
I have query 1.9.0 version. In response tag not appeare anything.
Before i used it many times but now i cant understand where is the bug.
You are violating the same origin policy restriction that's built in browsers. Your ASP.NET MVC application containing this javascript file is hosted on http://localhost:2197 but you are attempting to perform an AJAX request to http://localhost:21067 which cannot work.
There are some workarounds such as using JSONP (works only with GET requests) or CORS (works only in modern browsers that support it). If for some reason you cannot use some of those techniques you could have a server side controller action inside your ASP.NET MVC application which will perform the actual call to the remote domain and act as a bridge between the 2. Then from your client script you will send the AJAX request to your own domain.
IIS 8 & Windows 8
I have below sample code which I am trying to check whether a url exists, when I ran from console app it works fine, response is obtained, but when executed from server side ASP.net page it throws socket exception.
Sample code:
try
{
Uri uri = new Uri("HTTPS://test");
WebRequest http = HttpWebRequest.Create(uri);
HttpWebResponse response = (HttpWebResponse)http.GetResponse();
Stream stream = response.GetResponseStream();
}
catch (UriFormatException sds)
{
}
catch (IOException sdsd)
{
}
Error:
A connection attempt failed because the connected party did not properly respond after a period of time, or established connection failed because connected host has failed to respond
Any suggestions in this regard would helpful.
Without more information, my guess would be that the asp.net application is running under an account which does not have enough privs to access a network resource. You can try changing the account under which the asp.net application runs or impersonate a user with network access rights.