github.com/aarzilli/tools@v0.0.0-20151123112009-0d27094f75e0/net/http/proxy1/fetch_and_display.go (about)

     1  // Package proxy1 forwards html pages, simplifying their dom structure;
     2  // it is a wrapper around domclean2 for actual cleansing and proxification;
     3  // containing tamper-monkey javascript popup code.
     4  package proxy1
     5  
     6  import (
     7  	"bytes"
     8  	"fmt"
     9  	"mime"
    10  	"net/http"
    11  	"path"
    12  	"strings"
    13  
    14  	_ "html"
    15  
    16  	"github.com/pbberlin/tools/appengine/util_appengine"
    17  	"github.com/pbberlin/tools/net/http/domclean2"
    18  	"github.com/pbberlin/tools/net/http/fetch"
    19  	"github.com/pbberlin/tools/net/http/loghttp"
    20  	"github.com/pbberlin/tools/net/http/routes"
    21  	"github.com/pbberlin/tools/net/http/tplx"
    22  	"golang.org/x/net/html"
    23  )
    24  
    25  var insertNewlines = strings.NewReplacer(
    26  	"<head", "\n<head",
    27  	"</head>", "</head>\n",
    28  	"<meta", "\n<meta",
    29  	"</script>", "</script>\n",
    30  	"</style>", "</style>\n",
    31  	"</div>", "</div>\n",
    32  	"<style", "\n<style",
    33  	"<script", "\n<script")
    34  
    35  var replTabsNewline = strings.NewReplacer("\n", " ", "\t", " ")
    36  var undouble = strings.NewReplacer("\n\n\n", "\n", "\n\n", "\n")
    37  
    38  const c_formFetchUrl = `
    39  
    40  	<style> .ib { display:inline-block; }</style>
    41      <form action="{{.protocol}}://{{.host}}{{.path}}" method="post" >
    42        <div style='margin:8px;'>
    43        	<span class='ib' style='width:140px'>URL </span>
    44        	  <input name="{{.name}}"           size="80"  value="{{.val}}"><br/>
    45        	<span class='ib' style='width:140px'>Put into pre tags </span>
    46        	  <input name="renderInPre"    size="4"    value='' ><br/>
    47        	<span class='ib' style='width:140px'> </span>
    48        
    49        	<input type="submit" value="Fetch" accesskey='f'></div>
    50      </form>
    51  
    52  `
    53  
    54  // handleFetchURL either displays a form for requesting an url
    55  // or it returns the URL“s contents.
    56  func handleFetchURL(w http.ResponseWriter, r *http.Request, m map[string]interface{}) {
    57  
    58  	lg, b := loghttp.BuffLoggerUniversal(w, r)
    59  	_ = b
    60  
    61  	// on live server => always use https
    62  	if r.URL.Scheme != "https" && !util_appengine.IsLocalEnviron() {
    63  		r.URL.Scheme = "https"
    64  		r.URL.Host = r.Host
    65  		lg("lo - redirect %v", r.URL.String())
    66  		http.Redirect(w, r, r.URL.String(), http.StatusFound)
    67  	}
    68  
    69  	/*
    70  		To distinguish between posted and getted value,
    71  		we check the "post-only" slice of values first.
    72  		If nothing's there, but FormValue *has* a value,
    73  		then it was "getted", otherwise "posted"
    74  	*/
    75  	rURL := ""
    76  	urlAs := ""
    77  	err := r.ParseForm()
    78  	lg(err)
    79  	if r.PostFormValue(routes.URLParamKey) != "" {
    80  		urlAs += "url posted "
    81  		rURL = r.PostFormValue(routes.URLParamKey)
    82  	}
    83  
    84  	if r.FormValue(routes.URLParamKey) != "" {
    85  		if rURL == "" {
    86  			urlAs += "url getted "
    87  			rURL = r.FormValue(routes.URLParamKey)
    88  		}
    89  	}
    90  	// lg("received %v:  %q", urlAs, rURL)
    91  
    92  	if len(rURL) == 0 {
    93  
    94  		tplAdder, tplExec := tplx.FuncTplBuilder(w, r)
    95  		tplAdder("n_html_title", "Fetch some http data", nil)
    96  
    97  		m := map[string]string{
    98  			"protocol": "https",
    99  			"host":     r.Host, // not  fetch.HostFromReq(r)
   100  			"path":     routes.ProxifyURI,
   101  			"name":     routes.URLParamKey,
   102  			"val":      "google.com",
   103  		}
   104  		if util_appengine.IsLocalEnviron() {
   105  			m["protocol"] = "http"
   106  		}
   107  		tplAdder("n_cont_0", c_formFetchUrl, m)
   108  		tplExec(w, r)
   109  
   110  	} else {
   111  
   112  		r.Header.Set("X-Custom-Header-Counter", "nocounter")
   113  
   114  		bts, inf, err := fetch.UrlGetter(r, fetch.Options{URL: rURL})
   115  		lg(err)
   116  
   117  		tp := mime.TypeByExtension(path.Ext(inf.URL.Path))
   118  		if false {
   119  			ext := path.Ext(rURL)
   120  			ext = strings.ToLower(ext)
   121  			tp = mime.TypeByExtension(ext)
   122  		}
   123  		w.Header().Set("Content-Type", tp)
   124  		// w.Header().Set("Content-type", "text/html; charset=latin-1")
   125  
   126  		if r.FormValue("dbg") != "" {
   127  			w.Header().Set("Content-type", "text/html; charset=utf-8")
   128  			fmt.Fprintf(w, "%s<br>\n  %s<br>\n %v", inf.URL.Path, tp, inf.URL.String())
   129  			return
   130  		}
   131  
   132  		opts := domclean2.CleaningOptions{Proxify: true}
   133  		opts.Beautify = true // "<a> Linktext without trailing space"
   134  		opts.RemoteHost = fetch.HostFromStringUrl(rURL)
   135  
   136  		// opts.ProxyHost = routes.AppHost()
   137  		opts.ProxyHost = fetch.HostFromReq(r)
   138  		if !util_appengine.IsLocalEnviron() {
   139  			opts.ProxyHost = fetch.HostFromReq(r)
   140  		}
   141  
   142  		doc, err := domclean2.DomClean(bts, opts)
   143  
   144  		var bufRend bytes.Buffer
   145  		err = html.Render(&bufRend, doc)
   146  		lg(err)
   147  		w.Write(bufRend.Bytes())
   148  
   149  	}
   150  
   151  }
   152  
   153  func init() {
   154  	http.HandleFunc(routes.ProxifyURI, loghttp.Adapter(handleFetchURL))
   155  }