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 }