Mercurial > Grille > Grille-Config
comparison Controllers/ReportController.cs @ 0:689cde763395
init cimmit
author | Franklin Schmit <meokcin@gmail.com> |
---|---|
date | Thu, 05 Sep 2024 10:16:16 +0800 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:689cde763395 |
---|---|
1 using System; | |
2 using System.IO; | |
3 using System.Linq; | |
4 using System.Net; | |
5 using System.Net.Http; | |
6 using System.Text; | |
7 using System.Text.RegularExpressions; | |
8 using System.Threading.Tasks; | |
9 using Microsoft.AspNetCore.Http; | |
10 using Microsoft.AspNetCore.Http.Extensions; | |
11 using Microsoft.AspNetCore.Mvc; | |
12 | |
13 namespace Grille2.Controllers | |
14 { | |
15 public partial class ReportController : Controller | |
16 { | |
17 [HttpGet("/__ssrsreport")] | |
18 public async Task Get(string url) | |
19 { | |
20 if (!String.IsNullOrEmpty(url)) | |
21 { | |
22 using (var httpClient = CreateHttpClient()) | |
23 { | |
24 var responseMessage = await ForwardRequest(httpClient, Request, url); | |
25 | |
26 CopyResponseHeaders(responseMessage, Response); | |
27 | |
28 await WriteResponse(Request, url, responseMessage, Response, false); | |
29 } | |
30 } | |
31 } | |
32 | |
33 [Route("/ssrsproxy/{*url}")] | |
34 public async Task Proxy() | |
35 { | |
36 var urlToReplace = String.Format("{0}://{1}{2}/{3}/", Request.Scheme, Request.Host.Value, Request.PathBase, "ssrsproxy"); | |
37 var requestedUrl = Request.GetDisplayUrl().Replace(urlToReplace, "", StringComparison.InvariantCultureIgnoreCase); | |
38 var reportServerIndex = requestedUrl.IndexOf("/ReportServer", StringComparison.InvariantCultureIgnoreCase); | |
39 if (reportServerIndex == -1) | |
40 { | |
41 reportServerIndex = requestedUrl.IndexOf("/Reports", StringComparison.InvariantCultureIgnoreCase); | |
42 } | |
43 var reportUrlParts = requestedUrl.Substring(0, reportServerIndex).Split('/'); | |
44 | |
45 var url = String.Format("{0}://{1}:{2}{3}", reportUrlParts[0], reportUrlParts[1], reportUrlParts[2], | |
46 requestedUrl.Substring(reportServerIndex, requestedUrl.Length - reportServerIndex)); | |
47 | |
48 using (var httpClient = CreateHttpClient()) | |
49 { | |
50 var responseMessage = await ForwardRequest(httpClient, Request, url); | |
51 | |
52 CopyResponseHeaders(responseMessage, Response); | |
53 | |
54 if (Request.Method == "POST") | |
55 { | |
56 await WriteResponse(Request, url, responseMessage, Response, true); | |
57 } | |
58 else | |
59 { | |
60 if (responseMessage.Content.Headers.ContentType != null && responseMessage.Content.Headers.ContentType.MediaType == "text/html") | |
61 { | |
62 await WriteResponse(Request, url, responseMessage, Response, false); | |
63 } | |
64 else | |
65 { | |
66 using (var responseStream = await responseMessage.Content.ReadAsStreamAsync()) | |
67 { | |
68 await responseStream.CopyToAsync(Response.Body, 81920, HttpContext.RequestAborted); | |
69 } | |
70 } | |
71 } | |
72 } | |
73 } | |
74 | |
75 partial void OnHttpClientHandlerCreate(ref HttpClientHandler handler); | |
76 | |
77 private HttpClient CreateHttpClient() | |
78 { | |
79 var httpClientHandler = new HttpClientHandler(); | |
80 | |
81 httpClientHandler.AllowAutoRedirect = true; | |
82 httpClientHandler.UseDefaultCredentials = true; | |
83 | |
84 if (httpClientHandler.SupportsAutomaticDecompression) | |
85 { | |
86 httpClientHandler.AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate; | |
87 } | |
88 | |
89 OnHttpClientHandlerCreate(ref httpClientHandler); | |
90 | |
91 return new HttpClient(httpClientHandler); | |
92 } | |
93 | |
94 partial void OnReportRequest(ref HttpRequestMessage requestMessage); | |
95 | |
96 async Task<HttpResponseMessage> ForwardRequest(HttpClient httpClient, HttpRequest currentReqest, string url) | |
97 { | |
98 var proxyRequestMessage = new HttpRequestMessage(new HttpMethod(currentReqest.Method), url); | |
99 | |
100 foreach (var header in currentReqest.Headers) | |
101 { | |
102 if (header.Key != "Host") | |
103 { | |
104 proxyRequestMessage.Headers.TryAddWithoutValidation(header.Key, new string[] { header.Value }); | |
105 } | |
106 } | |
107 | |
108 this.OnReportRequest(ref proxyRequestMessage); | |
109 | |
110 if (currentReqest.Method == "POST") | |
111 { | |
112 using (var stream = new MemoryStream()) | |
113 { | |
114 await currentReqest.Body.CopyToAsync(stream); | |
115 stream.Position = 0; | |
116 | |
117 string body = new StreamReader(stream).ReadToEnd(); | |
118 proxyRequestMessage.Content = new StringContent(body); | |
119 | |
120 if (body.IndexOf("AjaxScriptManager") != -1) | |
121 { | |
122 proxyRequestMessage.Content.Headers.Remove("Content-Type"); | |
123 proxyRequestMessage.Content.Headers.Add("Content-Type", new string[] { currentReqest.ContentType }); | |
124 } | |
125 } | |
126 } | |
127 | |
128 return await httpClient.SendAsync(proxyRequestMessage); | |
129 } | |
130 | |
131 static void CopyResponseHeaders(HttpResponseMessage responseMessage, HttpResponse response) | |
132 { | |
133 response.StatusCode = (int)responseMessage.StatusCode; | |
134 foreach (var header in responseMessage.Headers) | |
135 { | |
136 response.Headers[header.Key] = header.Value.ToArray(); | |
137 } | |
138 | |
139 foreach (var header in responseMessage.Content.Headers) | |
140 { | |
141 response.Headers[header.Key] = header.Value.ToArray(); | |
142 } | |
143 | |
144 response.Headers.Remove("transfer-encoding"); | |
145 } | |
146 | |
147 static async Task WriteResponse(HttpRequest currentReqest, string url, HttpResponseMessage responseMessage, HttpResponse response, bool isAjax) | |
148 { | |
149 var result = await responseMessage.Content.ReadAsStringAsync(); | |
150 | |
151 var ReportServer = url.Contains("/ReportServer/", StringComparison.InvariantCultureIgnoreCase) ? "ReportServer" : "Reports"; | |
152 | |
153 var reportUri = new Uri(url); | |
154 var proxyUrl = String.Format("{0}://{1}{2}/ssrsproxy/{3}/{4}/{5}", currentReqest.Scheme, currentReqest.Host.Value, currentReqest.PathBase, | |
155 reportUri.Scheme, reportUri.Host, reportUri.Port); | |
156 | |
157 if (isAjax && result.IndexOf("|") != -1) | |
158 { | |
159 var builder = new StringBuilder(); | |
160 | |
161 var delimiterIndex = 0; | |
162 var length = 0; | |
163 var index = 0; | |
164 | |
165 var type = ""; | |
166 var id = ""; | |
167 var content = ""; | |
168 | |
169 while (index < result.Length) | |
170 { | |
171 delimiterIndex = result.IndexOf("|", index); | |
172 if (delimiterIndex == -1) | |
173 { | |
174 break; | |
175 } | |
176 length = int.Parse(result.Substring(index, delimiterIndex - index)); | |
177 if ((length % 1) != 0) | |
178 { | |
179 break; | |
180 } | |
181 index = delimiterIndex + 1; | |
182 delimiterIndex = result.IndexOf("|", index); | |
183 if (delimiterIndex == -1) | |
184 { | |
185 break; | |
186 } | |
187 type = result.Substring(index, delimiterIndex - index); | |
188 index = delimiterIndex + 1; | |
189 delimiterIndex = result.IndexOf("|", index); | |
190 if (delimiterIndex == -1) | |
191 { | |
192 break; | |
193 } | |
194 id = result.Substring(index, delimiterIndex - index); | |
195 index = delimiterIndex + 1; | |
196 if ((index + length) >= result.Length) | |
197 { | |
198 break; | |
199 } | |
200 content = result.Substring(index, length); | |
201 index += length; | |
202 if (result.Substring(index, 1) != "|") | |
203 { | |
204 break; | |
205 } | |
206 index++; | |
207 | |
208 content = content.Replace($"/{ReportServer}/", $"{proxyUrl}/{ReportServer}/", StringComparison.InvariantCultureIgnoreCase); | |
209 if (content.Contains("./ReportViewer.aspx", StringComparison.InvariantCultureIgnoreCase)) | |
210 { | |
211 content = content.Replace("./ReportViewer.aspx", $"{proxyUrl}/{ReportServer}/Pages/ReportViewer.aspx", StringComparison.InvariantCultureIgnoreCase); | |
212 } | |
213 else | |
214 { | |
215 content = content.Replace("ReportViewer.aspx", $"{proxyUrl}/{ReportServer}/Pages/ReportViewer.aspx", StringComparison.InvariantCultureIgnoreCase); | |
216 } | |
217 | |
218 builder.Append(String.Format("{0}|{1}|{2}|{3}|", content.Length, type, id, content)); | |
219 } | |
220 | |
221 result = builder.ToString(); | |
222 } | |
223 else | |
224 { | |
225 result = result.Replace($"/{ReportServer}/", $"{proxyUrl}/{ReportServer}/", StringComparison.InvariantCultureIgnoreCase); | |
226 | |
227 if (result.Contains("./ReportViewer.aspx", StringComparison.InvariantCultureIgnoreCase)) | |
228 { | |
229 result = result.Replace("./ReportViewer.aspx", $"{proxyUrl}/{ReportServer}/Pages/ReportViewer.aspx", StringComparison.InvariantCultureIgnoreCase); | |
230 } | |
231 else | |
232 { | |
233 result = result.Replace("ReportViewer.aspx", $"{proxyUrl}/{ReportServer}/Pages/ReportViewer.aspx", StringComparison.InvariantCultureIgnoreCase); | |
234 } | |
235 } | |
236 | |
237 response.Headers.Remove("Content-Length"); | |
238 response.Headers.Append("Content-Length", new string[] { System.Text.Encoding.UTF8.GetByteCount(result).ToString() }); | |
239 | |
240 await response.WriteAsync(result); | |
241 } | |
242 } | |
243 } |