我有一个Web服务需要从客户端接收请求,在调整URL后将其转发到后端服务,然后将响应发送回客户端。
然而,当我运行它并将浏览器指向我的服务时,浏览器就坐在那里等待响应并最终超时。
如果我在调试器中单步执行该服务,它将执行一切正常并成功从ProcessRequest方法返回。
如果我检查Fiddler中的流量,我可以看到我的服务发回了正确的响应标头,但似乎没有响应的主体。
我的代码是:
public class ForwardRequest : IHttpHandler
{
public bool IsReusable { get { return false; } }
public void ProcessRequest(HttpContext context)
{
try
{
Uri url = ConstructURL(context.Request.Url);
// Create the request object that we'll use to forward the request
HttpWebRequest forwardRequest = WebRequest.Create(url) as HttpWebRequest;
CopyRequestHeaders(context.Request, forwardRequest);
// Get the response back
HttpWebResponse response = forwardRequest.GetResponse() as HttpWebResponse;
// Copy the response back to the client
CopyResponseHeaders(response, context.Response);
using (Stream answer = response.GetResponseStream())
{
answer.CopyTo(context.Response.OutputStream);
context.Response.Flush();
}
}
catch (Exception ex)
{
...
}
finally
{
// make sure the response is closed properly.
try { context.ApplicationInstance.CompleteRequest(); }
catch { };
}
}
// Copy headers (and other info) from one response object to another
private void CopyResponseHeaders(HttpWebResponse source, HttpResponse destination)
{
foreach (var headerKey in source.Headers.AllKeys)
{
destination.Headers[headerKey] = source.Headers[headerKey];
}
destination.ContentType = source.ContentType;
}
// Copy headers (and other info) from one request object to another
// This method copied from a post on Stackoverflow.com
private void CopyRequestHeaders(HttpRequest source, HttpWebRequest destination)
{
destination.Method = source.HttpMethod;
// Copy the headers we're able to
foreach (var headerKey in source.Headers.AllKeys)
{
switch (headerKey)
{
case "Connection":
case "Content-Length":
case "Date":
case "Expect":
case "Host":
case "If-Modified-Since":
case "Range":
case "Transfer-Encoding":
case "Proxy-Connection":
// Let IIS handle these
break;
case "Accept":
case "Content-Type":
case "Referer":
case "User-Agent":
// Restricted - copied below
break;
default:
destination.Headers[headerKey] = source.Headers[headerKey];
break;
}
}
// Copy restricted headers
if (source.AcceptTypes.Any())
{
destination.Accept = string.Join(",", source.AcceptTypes);
}
destination.ContentType = source.ContentType;
if (source.UrlReferrer != null)
{
destination.Referer = source.UrlReferrer.AbsoluteUri;
}
destination.UserAgent = source.UserAgent;
// Copy content (if content body is allowed)
if (source.HttpMethod != "GET" && source.HttpMethod != "HEAD" && source.ContentLength > 0)
{
var destinationStream = destination.GetRequestStream();
source.InputStream.CopyTo(destinationStream);
destinationStream.Close();
}
}
}
我是否可能将对context.Response对象的初始响应复制错误?为什么我的服务请求似乎永远不会完成?
答案 0 :(得分:1)
我的请求超时时遇到了类似的问题。上次我遇到这个问题时,它与未正确关闭连接有关,并且没有可用的套接字,因此整个应用程序只是挂起。
以下是我用来发送http帖子请求的代码段。
public void Run() {
string url = "http://example.com/api";
string contentType = "application/xml";
string postData = "<this><is><my>xml</my></is></this>";
string responseBody = PostRequest(url, contentType, postData);
}
public string PostRequest(string url, string contentType, string postData)
{
try
{
HttpWebRequest request = (HttpWebRequest) WebRequest.Create(url);
request.Method = "POST";
request.ContentType = "application/xml";
request.Timeout = 30000;
request.ReadWriteTimeout = 30000;
Log.Debug("HTTP request: [" + request.Method + "] " + url);
byte[] byteArray = Encoding.UTF8.GetBytes(postData);
request.ContentLength = byteArray.Length;
Stream dataStream = request.GetRequestStream();
dataStream.Write(byteArray, 0, byteArray.Length);
dataStream.Close();
var response = (HttpWebResponse) request.GetResponse();
Log.Debug("HTTP response: " + response.StatusCode + " - " + response.StatusDescription);
StreamReader reader = new StreamReader(response.GetResponseStream());
string responseBody = reader.ReadToEnd();
response.Close();
return responseBody;
}
catch (Exception e)
{
Log.Error("Exception while running HTTP request.", e);
throw e;
}
}