<commit_before>//	Copyright 2013 slowfei And The Contributors All rights reserved.
//
//   Licensed under the Apache License, Version 2.0 (the "License");
//   you may not use this file except in compliance with the License.
//   You may obtain a copy of the License at
//
//       http://www.apache.org/licenses/LICENSE-2.0
//
//   Unless required by applicable law or agreed to in writing, software
//   distributed under the License is distributed on an "AS IS" BASIS,
//   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//   See the License for the specific language governing permissions and
//   limitations under the License.

//	leafveingo web 每次请求的上下文封装
//
//	email	<EMAIL>
//	createTime 	2013-9-13
//	updateTime	2013-10-9
package leafveingo

import (
	"bytes"
	"compress/flate"
	"compress/gzip"
	"github.com/slowfei/gosfcore/log"
	"github.com/slowfei/gosfcore/utils/strings"
	"github.com/slowfei/leafveingo/session"
	"io"
	"io/ioutil"
	"net/http"
	"strings"
)

const (
	HTML_FORM_TOKEN_NAME = "formToken"
)

//	request context
type HttpContext struct {
	RespWrite       http.ResponseWriter
	Request         *http.Request
	reqBody         []byte
	session         LVSession.HttpSession
	routerKeys      []string  // router keys
	methodNames     []string  // request controller method names
	contentEncoding string    // 压缩类型存储
	comperssWriter  io.Writer //
}

//	new context
func newContext(rw http.ResponseWriter, req *http.Request, respWirteCompress bool) *HttpContext {
	var outWrite io.Writer
	var err error
	acceptEncoding := strings.ToLower(req.Header.Get("Accept-Encoding"))
	encoding := "none"

	if respWirteCompress && 0 <= strings.Index(acceptEncoding, "gzip") {
		encoding = "gzip"
		outWrite, err = gzip.NewWriterLevel(rw, gzip.BestSpeed)
	} else if respWirteCompress && 0 <= strings.Index(acceptEncoding, "deflate") {
		encoding = "deflate"
		outWrite, err = flate.NewWriter(rw, flate.BestSpeed)
	} else {
		outWrite = rw
	}

	if nil != err {
		encoding = "none"
		outWrite = rw
	}

	return &HttpContext{RespWrite: rw, Request: req, reqBody: nil, session: nil, contentEncoding: encoding, comperssWriter: outWrite}
}

// colse comperss writer
func (ctx *HttpContext) closeWriter() {
	switch ow := ctx.comperssWriter.(type) {
	case *gzip.Writer:
		ow.Close()
	case *flate.Writer:
		ow.Close()
	case http.ResponseWriter:
	default:
		SFLog.Error("出现未知的压缩数据类型：(%T) 可能没有进行释放.", ow)
	}
}

//	get session, context the only session
//	@resetToken is reset session token
func (ctx *HttpContext) Session(resetToken bool) (LVSession.HttpSession, error) {
	if nil == _thisLeafvein.HttpSessionManager() {
		return nil, ErrHttpSessionManagerClosed
	}
	if nil == ctx.session {
		var sessError error
		ctx.session, sessError = _thisLeafvein.HttpSessionManager().GetSession(ctx.RespWrite, ctx.Request, _thisLeafvein.SessionMaxlifeTime(), resetToken)
		if nil != sessError {
			SFLog.Error("get session error:%v", sessError)
			return nil, sessError
		}
	}
	return ctx.session, nil
}

//	get string form token
//	Note: each access will change
func (ctx *HttpContext) FormTokenString() string {
	session, err := ctx.Session(false)
	if nil == session || nil != err {
		return ""
	}
	return session.FormTokenSignature()
}

//	get html input form token
//	Note: each access will change
func (ctx *HttpContext) FormTokenHTML() string {
	session, err := ctx.Session(false)
	if nil == session || nil != err {
		return ""
	}
	return `<input type="hidden" name="` + HTML_FORM_TOKEN_NAME + `" value="` + session.FormTokenSignature() + `"/>`
}

//	get javascript the out form token, (主要防止页面抓取)
//	Note: each access will change
func (ctx *HttpContext) FormTokenJavascript() string {
	session, err := ctx.Session(false)
	if nil == session || nil != err {
		return ""
	}

	// `
	// <script type="text/javascript">
	// /*<![CDATA[*/
	// /***********************************************
	// * Encrypt Email script- Please keep notice intact
	// * Tool URL: http://www.dynamicdrive.com/emailriddler/
	// * **********************************************/
	// <!-- Encrypted version of: you [at] **********.*** //-->
	// var emailriddlerarray=[121,111,117,64,121,111,117,114,100,111,109,97,105,110,46,99,111,109]
	// var encryptedemail_id85='' //variable to contain encrypted email
	// for (var i=0; i<emailriddlerarray.length; i++)
	//  encryptedemail_id85+=String.fromCharCode(emailriddlerarray[i])
	// document.write('<a href="mailto:'+encryptedemail_id85+'">Contact Us</a>')
	// /*]]>*/
	// </script>
	// `

	token := session.FormTokenSignature()
	tokenByte := []byte(token)
	tblen := len(tokenByte)

	// 参考：http://www.dynamicdrive.com/emailriddler/
	// stript := `<script type="text/javascript"></script>`

	//	TODO 暂时还没有想到好方法实现
	return ""
}

//	check form token
func (ctx *HttpContext) CheckFormToken() bool {

	formVals := ctx.Request.Form
	if 0 == len(formVals) {
		return false
	}

	hideVal := ctx.Request.Form.Get(HTML_FORM_TOKEN_NAME)
	if 0 == len(hideVal) {
		return false
	}

	session, err := ctx.Session(false)
	if nil == session || nil != err {<commit_msg>修改编译错误的代码。<commit_after>//	Copyright 2013 slowfei And The Contributors All rights reserved.
//
//   Licensed under the Apache License, Version 2.0 (the "License");
//   you may not use this file except in compliance with the License.
//   You may obtain a copy of the License at
//
//       http://www.apache.org/licenses/LICENSE-2.0
//
//   Unless required by applicable law or agreed to in writing, software
//   distributed under the License is distributed on an "AS IS" BASIS,
//   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//   See the License for the specific language governing permissions and
//   limitations under the License.

//	leafveingo web 每次请求的上下文封装
//
//	email	<EMAIL>
//	createTime 	2013-9-13
//	updateTime	2013-10-9
package leafveingo

import (
	"bytes"
	"compress/flate"
	"compress/gzip"
	"github.com/slowfei/gosfcore/log"
	"github.com/slowfei/leafveingo/session"
	"io"
	"io/ioutil"
	"net/http"
	"strings"
)

const (
	HTML_FORM_TOKEN_NAME = "formToken"
)

//	request context
type HttpContext struct {
	RespWrite       http.ResponseWriter
	Request         *http.Request
	reqBody         []byte
	session         LVSession.HttpSession
	routerKeys      []string  // router keys
	methodNames     []string  // request controller method names
	contentEncoding string    // 压缩类型存储
	comperssWriter  io.Writer //
}

//	new context
func newContext(rw http.ResponseWriter, req *http.Request, respWirteCompress bool) *HttpContext {
	var outWrite io.Writer
	var err error
	acceptEncoding := strings.ToLower(req.Header.Get("Accept-Encoding"))
	encoding := "none"

	if respWirteCompress && 0 <= strings.Index(acceptEncoding, "gzip") {
		encoding = "gzip"
		outWrite, err = gzip.NewWriterLevel(rw, gzip.BestSpeed)
	} else if respWirteCompress && 0 <= strings.Index(acceptEncoding, "deflate") {
		encoding = "deflate"
		outWrite, err = flate.NewWriter(rw, flate.BestSpeed)
	} else {
		outWrite = rw
	}

	if nil != err {
		encoding = "none"
		outWrite = rw
	}

	return &HttpContext{RespWrite: rw, Request: req, reqBody: nil, session: nil, contentEncoding: encoding, comperssWriter: outWrite}
}

// colse comperss writer
func (ctx *HttpContext) closeWriter() {
	switch ow := ctx.comperssWriter.(type) {
	case *gzip.Writer:
		ow.Close()
	case *flate.Writer:
		ow.Close()
	case http.ResponseWriter:
	default:
		SFLog.Error("出现未知的压缩数据类型：(%T) 可能没有进行释放.", ow)
	}
}

//	get session, context the only session
//	@resetToken is reset session token
func (ctx *HttpContext) Session(resetToken bool) (LVSession.HttpSession, error) {
	if nil == _thisLeafvein.HttpSessionManager() {
		return nil, ErrHttpSessionManagerClosed
	}
	if nil == ctx.session {
		var sessError error
		ctx.session, sessError = _thisLeafvein.HttpSessionManager().GetSession(ctx.RespWrite, ctx.Request, _thisLeafvein.SessionMaxlifeTime(), resetToken)
		if nil != sessError {
			SFLog.Error("get session error:%v", sessError)
			return nil, sessError
		}
	}
	return ctx.session, nil
}

//	get string form token
//	Note: each access will change
func (ctx *HttpContext) FormTokenString() string {
	session, err := ctx.Session(false)
	if nil == session || nil != err {
		return ""
	}
	return session.FormTokenSignature()
}

//	get html input form token
//	Note: each access will change
func (ctx *HttpContext) FormTokenHTML() string {
	session, err := ctx.Session(false)
	if nil == session || nil != err {
		return ""
	}
	return `<input type="hidden" name="` + HTML_FORM_TOKEN_NAME + `" value="` + session.FormTokenSignature() + `"/>`
}

//	get javascript the out form token, (主要防止页面抓取)
//	Note: each access will change
func (ctx *HttpContext) FormTokenJavascript() string {
	session, err := ctx.Session(false)
	if nil == session || nil != err {
		return ""
	}

	// `
	// <script type="text/javascript">
	// /*<![CDATA[*/
	// /***********************************************
	// * Encrypt Email script- Please keep notice intact
	// * Tool URL: http://www.dynamicdrive.com/emailriddler/
	// * **********************************************/
	// <!-- Encrypted version of: you [at] **********.*** //-->
	// var emailriddlerarray=[121,111,117,64,121,111,117,114,100,111,109,97,105,110,46,99,111,109]
	// var encryptedemail_id85='' //variable to contain encrypted email
	// for (var i=0; i<emailriddlerarray.length; i++)
	//  encryptedemail_id85+=String.fromCharCode(emailriddlerarray[i])
	// document.write('<a href="mailto:'+encryptedemail_id85+'">Contact Us</a>')
	// /*]]>*/
	// </script>
	// `

	token := session.FormTokenSignature()
	tokenByte := []byte(token)
	tblen := len(tokenByte)
	if 1 == tblen {

	}
	// 参考：http://www.dynamicdrive.com/emailriddler/
	// stript := `<script type="text/javascript"></script>`

	//	TODO 暂时还没有想到好方法实现
	return ""
}

//	check form token
func (ctx *HttpContext) CheckFormToken() bool {

	formVals := ctx.Request.Form
	if 0 == len(formVals) {
		return false
	}

	hideVal := ctx.Request.Form.Get(HTML_FORM_TOKEN_NAME)
	if 0 == len(hideVal) {
		return false
	}

	session, err := ctx.Session(false)
	if nil == session || nil != err {
{'fraction_non_alphanumeric': 0.15633636004737467, 'fraction_numerical': 0.016482431898934072, 'mean_word_length': 3.8344465648854964, 'pattern_counts': {'":': 0, '<': 29, '<?xml version=': 0, '>': 23, 'https://': 0, 'lorem ipsum': 0, 'www.': 6, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '162694', 'n_tokens_mistral': 3651, 'n_tokens_neox': 3476, 'n_words': 882}