-
Notifications
You must be signed in to change notification settings - Fork 0
/
proxy.ashx.cs
166 lines (146 loc) · 4.46 KB
/
proxy.ashx.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
/*
This proxy page does not have any security checks. It is highly recommended
that a user deploying this proxy page on their web server, add appropriate
security checks, for example checking request path, username/password, target
url, etc.
*/
using System;
using System.IO;
using System.Web;
namespace Proxy
{
/// <summary>
/// Forwards requests to an ArcGIS Server REST resource. Uses information in
/// the proxy.config file to determine properties of the server.
/// </summary>
public class proxy : IHttpHandler
{
public void ProcessRequest(HttpContext context)
{
HttpResponse response = context.Response;
// Get the URL requested by the client (take the entire querystring at once
// to handle the case of the URL itself containing querystring parameters)
string uri = context.Request.Url.Query.Substring(1);
// Get token, if applicable, and append to the request
string token = getTokenFromConfigFile(uri);
if (!String.IsNullOrEmpty(token))
{
if (uri.Contains("?"))
uri += "&token=" + token;
else
uri += "?token=" + token;
}
System.Net.HttpWebRequest req = (System.Net.HttpWebRequest)System.Net.HttpWebRequest.Create(uri);
req.Method = context.Request.HttpMethod;
req.ServicePoint.Expect100Continue = false;
req.Referer = context.Request.Headers["referer"];
// Set body of request for POST requests
if (context.Request.InputStream.Length > 0)
{
byte[] bytes = new byte[context.Request.InputStream.Length];
context.Request.InputStream.Read(bytes, 0, (int)context.Request.InputStream.Length);
req.ContentLength = bytes.Length;
string ctype = context.Request.ContentType;
if (String.IsNullOrEmpty(ctype))
{
req.ContentType = "application/x-www-form-urlencoded";
}
else
{
req.ContentType = ctype;
}
using (Stream outputStream = req.GetRequestStream())
{
outputStream.Write(bytes, 0, bytes.Length);
}
}
else
{
req.Method = "GET";
}
// Send the request to the server
System.Net.WebResponse serverResponse = null;
try
{
serverResponse = req.GetResponse();
}
catch (System.Net.WebException webExc)
{
response.StatusCode = 500;
response.StatusDescription = webExc.Status.ToString();
response.Write(webExc.Response);
response.End();
return;
}
// Set up the response to the client
if (serverResponse != null)
{
response.ContentType = serverResponse.ContentType;
using (Stream byteStream = serverResponse.GetResponseStream())
{
// Text response
if (serverResponse.ContentType.Contains("text") ||
serverResponse.ContentType.Contains("json") ||
serverResponse.ContentType.Contains("xml"))
{
using (StreamReader sr = new StreamReader(byteStream))
{
string strResponse = sr.ReadToEnd();
response.Write(strResponse);
}
}
else
{
// Binary response (image, lyr file, other binary file)
BinaryReader br = new BinaryReader(byteStream);
byte[] outb = br.ReadBytes((int)serverResponse.ContentLength);
br.Close();
// Tell client not to cache the image since it's dynamic
response.CacheControl = "no-cache";
// Send the image to the client
// (Note: if large images/files sent, could modify this to send in chunks)
response.OutputStream.Write(outb, 0, outb.Length);
}
serverResponse.Close();
}
}
response.End();
}
public bool IsReusable
{
get
{
return false;
}
}
// Gets the token for a server URL from a configuration file
// TODO: ?modify so can generate a new short-lived token from username/password in the config file
private string getTokenFromConfigFile(string uri)
{
try
{
ProxyConfig config = ProxyConfig.GetCurrentConfig();
if (config != null)
return config.GetToken(uri);
else
throw new ApplicationException(
"Proxy.config file does not exist at application root, or is not readable.");
}
catch (InvalidOperationException)
{
// Proxy is being used for an unsupported service (proxy.config has mustMatch="true")
HttpResponse response = HttpContext.Current.Response;
response.StatusCode = (int)System.Net.HttpStatusCode.Forbidden;
response.End();
}
catch (Exception e)
{
if (e is ApplicationException)
throw e;
// just return an empty string at this point
// -- may want to throw an exception, or add to a log file
}
return string.Empty;
}
}
}