Manipulating HTTP Response

2019-06-25 05:05发布

问题:

my current question is tightly related to this one, but is far more specific. We have to plan a design strategy for the objective described in that question.

We want to do this by rewriting HTML on ASP.NET web forms. My question is: which strategy is the best according to parameters of feasibility, performance impact and implementation effort on legacy applications.

What I have to do

is to basically get the HTML output of a Web Form, parse it, and replace certain URLs according to user-defined rules. In that example, I would rewrite all static content to CDN URLs, but it can be easily extended to URL rewriting techniques. I found lots (and I really mean lots) of articles about URL rewriting from the perspective of having URLs like http://myblog.com/2092 interpreted as http://myblog.com/Default.aspx?post=2092 but I found none showing me how to smartly format old-style URLs to shorter format right from inside HTML (so the page will render the short-form URL directly) [edit] without deep code intervention.

Strategy 1

Like suggested in an answer of the above question, write an HTTP Module that intercepts the HTML and rewrites it. Actually, I looked around and saw I can set a Response.Filter stream object that performs the HTML filtering.

  • Pros: I can inject the HTTP Module on a legacy application, configure rewriting rules via XML and have the oldest CRM/ecommerce application load static content from a CDN without touching its code at all.
  • Cons: I suspected that (and a comment here confirms my suspects) having to reimplement a Stream's Write method, which operates on a partial buffer in the general case, can result in bad replacements. Suppose the Write method is first called with a chunk like ttp://mydomain.com/static/ima (where I assume <img src="h was already written before) and later ge.png" /> (so guess the final URL :-P) with a rewrite rule that regexes http://mydomain.com/static/[^"]* into http://cdn.com/path/$1, the substitution is not done. To workaround that, I could use a MemoryStream or something like that to buffer the complete set of data and then perform the substitutions, but it could cause troubles on highly loaded servers

Strategy 2

Overriding Page's Render method in a way such as described here

  • Pros: doesn't suffer the chunking problem
  • Cons: requires defining a base class for all pages. Feasible on new applications, not sure for maintaining legacy applications. Seems has a problem as you cannot instantiate HttpTextWriter directly

Obviously, for the new webapps we'll have to develop, I would adopt strategy 2, but I really like using dynamic components a lot, as they can be plugged with ease when application requires them (so if our new app will be installed without a CDN the feature is turned off).

Briefly, my questions are

How would you fix both strategies' cons (particularly 1st)? And, of course, do you have other strategies to suggest to achieve this objective?

Thank you.

回答1:

Maybe you could use ASP.NET's "adaptive control behavior" feature. See Architectural Overview of Adaptive Control Behavior

Basically you would redefine a new HtmlTextWriter class, associate it as the default renderer, and override "A" tag rendering with your own code.