Пример #1
0
func makeRequest(w http.ResponseWriter, r *http.Request, path string) CGI_Result {

	c := appengine.NewContext(r)
	client := urlfetch.Client(c)

	url_exe := spf(`http://%s%s%s&ts=%s`, dns_cam, path, credentials, urlParamTS())
	url_dis := spf(`http://%s%s&ts=%s`, dns_cam, path, urlParamTS())
	wpf(w, "<div style='font-size:10px; line-height:11px;'>requesting %v<br></div>\n", url_dis)
	resp1, err := client.Get(url_exe)
	loghttp.E(w, r, err, false)

	bcont, err := ioutil.ReadAll(resp1.Body)
	defer resp1.Body.Close()
	loghttp.E(w, r, err, false)

	cgiRes := CGI_Result{}
	xmlerr := xml.Unmarshal(bcont, &cgiRes)
	loghttp.E(w, r, xmlerr, false)

	if cgiRes.Result != "0" {
		wpf(w, "<b>RESPONSE shows bad mood:</b><br>\n")
		psXml := stringspb.IndentedDump(cgiRes)
		dis := strings.Trim(psXml, "{}")
		wpf(w, "<pre style='font-size:10px;line-height:11px;'>%v</pre>", dis)
	}

	if debug {
		scont := string(bcont)
		wpf(w, "<pre style='font-size:10px;line-height:11px;'>%v</pre>", scont)
	}

	return cgiRes

}
Пример #2
0
func foscamStatus(w http.ResponseWriter, r *http.Request, m map[string]interface{}) {

	htmlfrag.SetNocacheHeaders(w)
	w.Header().Set("Content-Type", "text/html; charset=utf-8")

	logRetrieve(w, r)

	cgiRes := makeRequest(w, r, path_get_alarm)

	psXml := stringspb.IndentedDump(cgiRes)
	dis := strings.Trim(psXml, "{}")
	dis = strings.Replace(dis, "\t", "", -1)
	dis = strings.Replace(dis, " ", "", -1)
	dis = strings.Replace(dis, "\"", "", -1)
	dis = strings.Replace(dis, "\n", " ", -1)
	dis = strings.Replace(dis, "Area0", "\nArea0", -1)
	dis = strings.Replace(dis, "Schedule0", "\nSchedule0", -1)
	dis = strings.Replace(dis, "Log0", "\nLog0", -1)
	wpf(w, "<pre style='font-size:10px;line-height:11px;'>%v</pre>", dis)

	if cgiRes.IsEnable == "0" {
		wpf(w, "Status <b>DISabled</b><br><br>\n")
	} else {
		wpf(w, "Status <b>ENabled</b><br><br>\n")
	}

	imageRetrieve(w, r)

}
Пример #3
0
// GetDirContents fetches from fileserver - via http
// Parsing the received JSON into string slices
func GetDirContents(hostWithPrefix, dir string) ([]string, []string, *bytes.Buffer, error) {

	lg, lge := loghttp.Logger(nil, nil)
	_ = lg

	var b = new(bytes.Buffer)

	dirs := []string{}
	fils := []string{}

	// build url
	urlSubDirs, err := url.Parse(path.Join(hostWithPrefix, dir))
	lge(err)
	if err != nil {
		return dirs, fils, b, err
	}
	sd := urlSubDirs.String()
	sd = common.Directorify(sd)
	wpf(b, "requ subdirs from  %v", sd)

	// make req
	bsubdirs, effU, err := fetch.UrlGetter(nil, fetch.Options{URL: sd})
	lge(err)
	if err != nil {
		return dirs, fils, b, err
	}
	wpf(b, "got %s - %v", bsubdirs, effU)

	// parse json
	mpSubDir := []map[string]string{}
	err = json.Unmarshal(bsubdirs, &mpSubDir)
	lge(err)
	if err != nil {
		// lg("%s", bsubdirs)
		return dirs, fils, b, err
	}
	wpf(b, "json of subdir is %s", stringspb.IndentedDump(mpSubDir))

	for _, v := range mpSubDir {

		if dir, ok := v["path"]; ok {
			if strings.HasSuffix(dir, "/") {
				dirs = append(dirs, dir)
			} else {
				fils = append(fils, dir)
			}
		}

		if smod, ok := v["mod"]; ok {
			t, err := time.Parse(time.RFC1123Z, smod)
			lge(err)
			wpf(b, "age %-6.2v", time.Now().Sub(t).Hours())
		}

	}
	return dirs, fils, b, nil

}
Пример #4
0
// fetchCommandReceiver takes http post requests, extracts the JSON commands
// and submits them to FetchHTML
func fetchCommandReceiver(w http.ResponseWriter, r *http.Request, m map[string]interface{}) {

	lg, lge := loghttp.Logger(w, r)

	var fcs []FetchCommand

	// The type of resp.body  <io.Reader> lends itself to using decode.
	// http://stackoverflow.com/ - ... using-json-unmarshal-vs-json-newdecoder-decode
	//
	// Nevertheless, we use Unmarshal here, because we want to inspect the bytes of body.
	var Unmarshal_versus_Decode = true

	if Unmarshal_versus_Decode {

		body, err := ioutil.ReadAll(r.Body) // no response write until here !
		lge(err)

		if len(body) == 0 {
			lg("empty body")
			return
		}

		err = json.Unmarshal(body, &fcs)
		if err != nil {
			lge(err)
			lg("body is %s", body)
			return
		}

	} else {

		dec := json.NewDecoder(r.Body)
		for {
			if err := dec.Decode(&fcs); err == io.EOF {
				break
			} else if err != nil {
				lge(err)
				return
			}
			lg("command loop is: %s", stringspb.IndentedDump(fcs))
		}

	}

	FetchHTML(w, r, fcs)

}
Пример #5
0
func Tokenize() {

	extension := ".html"
	directory := ""

	ss := util.GetFilesByExtension(directory, extension, false)
	pss := stringspb.IndentedDump(ss)
	pf("%v \n\n", *pss)

	if len(ss) < 1 {
		pf("did not find any files with %q\n", extension)
		return
	}

	ss = ss[0:1]

	for i := 0; i < len(ss); i++ {
		sb, err := ioutil.ReadFile(ss[i])
		if err != nil {
			pf("%v \n", err)
		}

		r := bytes.NewReader(sb)
		b, err := cleanseHtml(r)
		if err != nil {
			pf("%v \n", err)
		}

		util.WriteBytesToFilename("xx_"+ss[i], b)

		//
		pf("\n\n")
		r = bytes.NewReader(b.Bytes())
		decomposeHtml(r)

	}

}
Пример #6
0
// UrlGetter universal http getter for app engine and standalone go programs.
// Previously response was returned. Forgot why. Dropped it.
func UrlGetter(gaeReq *http.Request, options Options) (
	[]byte, Info, error,
) {

	options.LogLevel = 2

	var err error
	var inf Info = Info{}

	if options.LogLevel > 0 {
		if options.Req != nil {
			inf.Msg += fmt.Sprintf("orig req url: %#v\n", options.Req.URL.String())
		} else {
			inf.Msg += fmt.Sprintf("orig str url: %#v\n", options.URL)
		}
	}

	//
	// Either take provided request
	// Or build one from options.URL
	if options.Req == nil {
		ourl, err := URLFromString(options.URL) // Normalize
		if err != nil {
			return nil, inf, err
		}
		options.URL = ourl.String()
		options.Req, err = http.NewRequest("GET", options.URL, nil)
		if err != nil {
			return nil, inf, err
		}
	} else {
		if options.Req.URL.Scheme == "" {
			options.Req.URL.Scheme = "https"
		}
	}
	r := options.Req

	if len(options.KnownProtocol) > 1 {
		if strings.HasSuffix(options.KnownProtocol, ":") {
			options.KnownProtocol = strings.TrimSuffix(options.KnownProtocol, ":")
		}
		if options.KnownProtocol == "http" || options.KnownProtocol == "https" {
			r.URL.Scheme = options.KnownProtocol
			inf.Msg += fmt.Sprintf("Using known protocol %q\n", options.KnownProtocol)
		}
	}

	//
	// Unifiy appengine plain http.client
	client := &http.Client{}
	if gaeReq == nil {
		client.Timeout = time.Duration(5 * time.Second) // GAE does not allow
	} else {
		c := util_appengine.SafelyExtractGaeContext(gaeReq)
		if c != nil {

			ctxOld := oldAE.NewContext(gaeReq)
			client = oldFetch.Client(ctxOld)

			// this does not prevent urlfetch: SSL_CERTIFICATE_ERROR
			// it merely leads to err = "DEADLINE_EXCEEDED"
			tr := oldFetch.Transport{Context: ctxOld, AllowInvalidServerCertificate: true}
			// thus
			tr = oldFetch.Transport{Context: ctxOld, AllowInvalidServerCertificate: false}

			tr.Deadline = 20 * time.Second // only possible on aeOld

			client.Transport = &tr
			// client.Timeout = 20 * time.Second // also not in google.golang.org/appengine/urlfetch

		} else {
			return nil, inf, ErrNoContext
		}

		// appengine dev server => always fallback to http
		if c != nil && appengine.IsDevAppServer() && !options.ForceHTTPSEvenOnDevelopmentServer {
			r.URL.Scheme = "http"
		}
	}

	inf.URL = r.URL

	if options.RedirectHandling == 1 {
		client.CheckRedirect = func(req *http.Request, via []*http.Request) error {

			if len(via) == 1 && req.URL.Path == via[0].URL.Path+"/" {
				// allow redirect from /gesundheit to /gesundheit/
				return nil
			}

			spath := "\n"
			for _, v := range via {
				spath += v.URL.Path + "\n"
			}
			spath += req.URL.Path + "\n"
			return fmt.Errorf("%v %v", MsgNoRdirects, spath)
		}
	}

	if options.LogLevel > 0 {
		inf.Msg += fmt.Sprintf("url standardized to %q  %q %q \n", r.URL.Scheme, r.URL.Host, r.URL.RequestURI())
	}

	//
	//
	// Respond to test.economist.com directly from memory
	if _, ok := TestData[r.URL.Host+r.URL.Path]; ok {
		return TestData[r.URL.Host+r.URL.Path], inf, nil
	}

	// The actual call
	// =============================

	resp, err := client.Do(r)

	// Swallow redirect errors
	if err != nil {
		if options.RedirectHandling == 1 {
			serr := err.Error()
			if strings.Contains(serr, MsgNoRdirects) {
				bts := []byte(serr)
				inf.Mod = time.Now().Add(-10 * time.Minute)
				return bts, inf, nil
			}
		}
	}

	isHTTPSProblem := false
	if err != nil {
		isHTTPSProblem = strings.Contains(err.Error(), "SSL_CERTIFICATE_ERROR") ||
			strings.Contains(err.Error(), "tls: oversized record received with length")
	}

	// Under narrow conditions => fallback to http
	if err != nil {
		if isHTTPSProblem && r.URL.Scheme == "https" && r.Method == "GET" {
			r.URL.Scheme = "http"
			var err2nd error
			resp, err2nd = client.Do(r)
			// while protocol http may go through
			// next obstacle might be - again - a redirect error:
			if err2nd != nil {
				if options.RedirectHandling == 1 {
					serr := err2nd.Error()
					if strings.Contains(serr, MsgNoRdirects) {
						bts := []byte(serr)
						inf.Mod = time.Now().Add(-10 * time.Minute)
						addFallBackSuccessInfo(options, &inf, r, err)
						return bts, inf, nil
					}
				}

				return nil, inf, fmt.Errorf("GET fallback to http failed with %v", err2nd)
			}
			addFallBackSuccessInfo(options, &inf, r, err)
			err = nil // CLEAR error
		}
	}

	//
	// Final error handler
	//
	if err != nil {
		hintAE := ""
		if isHTTPSProblem && r.URL.Scheme == "https" {
			// Not GET but POST:
			// We cannot do a fallback for a post request - the r.Body.Reader is consumed
			// options.r.URL.Scheme = "http"
			// resp, err = client.Do(options.Req)
			return nil, inf, fmt.Errorf("Cannot do https requests. Possible reason: Dev server: %v", err)
		} else if strings.Contains(
			err.Error(),
			"net/http: Client Transport of type init.failingTransport doesn't support CancelRequest; Timeout not supported",
		) {
			hintAE = "\nDid you forget to submit the AE Request?\n"
		}
		return nil, inf, fmt.Errorf("request failed: %v - %v", err, hintAE)
	}

	//
	// We got response, but
	// explicit bad response from server
	if resp.StatusCode != http.StatusOK {

		if resp.StatusCode == http.StatusBadRequest || // 400
			resp.StatusCode == http.StatusNotFound || // 404
			false {
			dmp := ""
			for k, v := range resp.Header {
				dmp += fmt.Sprintf("key: %v - val %v\n", k, v)
			}
			dmp = ""
			dmp += stringspb.IndentedDump(r.URL)

			bts, errRd := ioutil.ReadAll(resp.Body)
			if errRd != nil {
				return nil, inf, fmt.Errorf("cannot read resp body: %v", errRd)
			}
			if len(bts) > 2*1024 {
				btsApdx := append([]byte(" ...omitted... "), bts[len(bts)-100:]...)
				bts = append(bts[2*1024:], btsApdx...)
			}
			defer resp.Body.Close()

			err2 := fmt.Errorf("resp %v: %v \n%v \n<pre>%s</pre>", resp.StatusCode, r.URL.String(), dmp, bts)

			if r.URL.Path == "" {
				r.URL.Path = "/"
			}
			var err2nd error
			resp, err2nd = client.Do(r)
			if err2nd != nil {
				return nil, inf, fmt.Errorf("again error %v \n%v", err2nd, err2)
			}
			if resp.StatusCode != http.StatusOK {
				inf.Status = resp.StatusCode
				return nil, inf, fmt.Errorf("again Status NotOK %v \n%v", resp.StatusCode, err2)
			}
			log.Printf("successful retry with '/' to %v after %v\n", r.URL.String(), err)
			err = nil // CLEAR error

			// return nil, inf, err2

		} else {
			return nil, inf, fmt.Errorf("bad http resp code: %v - %v", resp.StatusCode, r.URL.String())
		}
	}

	bts, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		return nil, inf, fmt.Errorf("cannot read resp body: %v", err)
	}
	defer resp.Body.Close()

	// time stamp
	var tlm time.Time // time last modified
	lm := resp.Header.Get("Last-Modified")
	if lm != "" {
		tlm, err = time.Parse(time.RFC1123, lm) // Last-Modified: Sat, 29 Aug 2015 21:15:39 GMT
		if err != nil {
			tlm, err = time.Parse(time.RFC1123Z, lm) // with numeric time zone
			if err != nil {
				var zeroTime time.Time
				tlm = zeroTime
			}
		}
	}
	inf.Mod = tlm
	// log.Printf("    hdr  %v %v\n", lm, tlm.Format(time.ANSIC))

	return bts, inf, nil

}
Пример #7
0
/*

https://developers.coinbase.com/docs/merchants/callbacks


id				Order number used to uniquely identify an order on Coinbase
completed_at	ISO 8601 timestamp when the order completed
status			[completed, mispaid, expired]
event			[completed, mispayment]. If mispayment => check key mispayment_id. Distinction from status ...
total_btc		Total amount of the order in ‘satoshi’ (1 BTC = 100,000,000 Satoshi). Note the use of the word ‘cents’ in the callback really means satoshi in this context. The btc amount will be calculated at the current exchange rate at the time the order is placed (current to within 15 minutes).
total_native	Units of local currency. 1 unit = 100 cents. Equal to the price from creating the button.
total_payout	Units of local currency deposited using instant payout.
custom			Custom parameter from data-custom attribute of button. Usually an Order, User, or Product ID
receive_address	Bitcoin address associated with this order. This is where the payment was sent.
button			Button details. ID matches the data-code parameter in your embedded HTML code.
transaction		Hash and number of confirmations of underlying transaction.
				Number of confirmations typically zero at the time of the first callback.
customer		Customer information from order form. Can include email xor shipping address.
refund_address	Experimental parameter that is subject to change.


*/
func confirmPay(w http.ResponseWriter, r *http.Request, m map[string]interface{}) {

	lg, b := loghttp.BuffLoggerUniversal(w, r)
	closureOverBuf := func(bUnused *bytes.Buffer) {
		// loghttp.Pf(w, r, b.String())
	}
	defer closureOverBuf(b) // the argument is ignored,
	r.Header.Set("X-Custom-Header-Counter", "nocounter")

	htmlfrag.SetNocacheHeaders(w)

	//____________________________________________________________________

	bts, err := ioutil.ReadAll(r.Body)
	if err != nil {
		lg("cannot read resp body: %v", err)
		return
	}
	defer r.Body.Close()

	// lg("bytes are -%s-", stringspb.ToLen(string(bts), 20))

	if len(bts) < 1 {
		lg("lo empty post body")
		w.WriteHeader(http.StatusOK)
		b = new(bytes.Buffer)
		return
	}

	var mp map[string]interface{}
	err = json.Unmarshal(bts, &mp)
	lg(err)

	mpPayout := submap(mp, "payout", lg)
	if len(mpPayout) > 0 {
		lg("lo " + stringspb.IndentedDump(mpPayout))
	}
	mpAddress := submap(mp, "address", lg)
	if len(mpAddress) > 0 {
		lg("lo " + stringspb.IndentedDump(mpAddress))
	}

	var cents, BTC float64
	var status string

	mpOrder := submap(mp, "order", lg)
	if len(mpOrder) < 1 {
		w.WriteHeader(http.StatusLengthRequired)
		lg("mpOrder not present %v", status)
		return
	} else {
		lg("lo " + stringspb.IndentedDump(mpOrder))

		mpBTC := submap(mpOrder, "total_btc", lg)
		// lg("lo " + stringspb.IndentedDump(mpBTC))

		if icents, ok := mpBTC["cents"]; ok {
			cents, ok = icents.(float64)
			if !ok {
				lg(" mpBTC[cents] is of unexpected type %T ", mpBTC["cents"])
			}
			BTC = cents / (1000 * 1000 * 100)

		} else {
			lg(" mpBTC[cents] not present")
		}
		lg("received %18.2f satoshi, %2.9v BTC ", cents, BTC)

		if _, ok := mpOrder["status"]; ok {
			status, ok = mpOrder["status"].(string)
			if !ok {
				lg(" mpOrder[status] is of unexpected type %T ", mpOrder["status"])
			}
		}

		lg("status    %v  ", status)
		lg("custom   %#v  ", mpOrder["custom"])
		lg("customer %#v - mostly empty", mpOrder["customer"])

		var values url.Values
		if _, ok := mpOrder["custom"]; ok {
			if mpOrder["custom"] == "123456789" {
				lg("test request recognized")
				values = url.Values{}
				values.Add("uID", "testUser123")
				values.Add("productID", "/member/somearticle")
			} else {
				var err error
				values, err = url.ParseQuery(mpOrder["custom"].(string))
				lg(err)
				if err != nil {
					w.WriteHeader(http.StatusLengthRequired)
					lg("unsatisfactory query in custom string %v", mpOrder["custom"])
					return
				}
			}
		} else {
			w.WriteHeader(http.StatusLengthRequired)
			lg("custom string not present")
			return
		}

		//  save
		if status == "completed" {
			lg("status 'completed'")
			blob := dsu.WrapBlob{
				VByte: stringspb.IndentedDumpBytes(mpOrder),
			}
			blob.Name = values.Get("uID")
			blob.Category = "invoice"
			blob.S = values.Get("productID")
			blob.Desc = status
			blob.F = BTC
			blob.I = int(time.Now().Unix())

			// blob.VVByte, _ = conv.String_to_VVByte(string(blob.VByte)) // just to make it readable

			newKey, err := dsu.BufPut(appengine.NewContext(r), blob, blob.Name+blob.S)
			lg("key is %v", newKey)
			lg(err)

			retrieveAgain, err := dsu.BufGet(appengine.NewContext(r), "dsu.WrapBlob__"+blob.Name+blob.S)
			lg(err)
			lg("retrieved %v %v %v", retrieveAgain.Name, retrieveAgain.Desc, retrieveAgain.F)

		} else {
			w.WriteHeader(http.StatusLengthRequired)
			lg("unsatisfactory status %v", status)
			return
		}

	}
	w.WriteHeader(http.StatusOK)
	b = new(bytes.Buffer)

}