<?php /** * PD * ProxyDebug * * @author kun* @copyright 2014 kun * @license http://www.php.net/license/3_01.txt PHP License 3.01 * @version 1.0 * @link https://github.com/yangxikun/tag-parse * @since 1.0 */ /** * PD * * @author rokety* @license http://www.php.net/license/3_01.txt PHP License 3.01 * @version 1.0 * @link * @since 1.0 */ class PD { protected static $debugItemCount = 0; protected static $debugGroupCount = 0; protected static $group = array(); protected static $start; protected static $offset = 0; protected static $varNameString = null; /** * getVarName * get the variable name * * @access protected * @static * * @return string */ protected static function getVarName() { if (self::$varNameString === null) { $trace = debug_backtrace(); $line = file($trace[3]['file']); self::$varNameString = $line[$trace[3]['line']-1]; } preg_match( '~\$([\w\d_]+)~', self::$varNameString, $matches, PREG_OFFSET_CAPTURE, self::$offset ); if (!isset($matches[1])) { throw new Exception('Error Params, should use $variable as params', 1); } self::$offset = $matches[1][1]; return $matches[1][0]; } /** * func * * @param string $type debug type(info, warn, error) * @param mixed $arg debug variable * * @access protected * @static * * @return null */ protected static function func($type, $arg) { if (self::$start) { self::$group[] = array( "category"=>$type, "type"=>gettype($arg), "name"=>self::getVarName(), "value"=>$arg ); } else { self::$debugItemCount++; header( 'Proxy_debug_item_'.self::$debugItemCount.': ' .json_encode( ["category"=>$type, "type"=>gettype($arg), "name"=>self::getVarName(), "value"=>$arg] ) ); header('Proxy_debug_item_count: '.self::$debugItemCount); } } public static function __callStatic($name, $args) { $func = ['info'=>'I', 'warn'=>'W', 'error'=>'E']; if (isset($func[$name])) { self::$offset = 0; self::$varNameString = null; foreach ($args as $key => $arg) { self::func($func[$name], $arg); } } else { throw new Exception('Call to undefined method!', 1); } } /** * groupStart * start record a group * * @access public * @static * * @return null */ public static function groupStart() { self::$start = true; self::$debugGroupCount++; } /** * groupEnd * stop record a group * * @access public * @static * * @return null */ public static function groupEnd() { self::$start = false; header( 'Proxy_debug_group_' .self::$debugGroupCount .': '.json_encode(self::$group) ); header('Proxy_debug_group_count: '.self::$debugGroupCount); self::$group = array(); } }
2. [文件] main.go ~ 6KB
//Proxy Debug //This simple program is for helping developers debug through http header. //For more detail, see README.md package main import ( "bufio" "encoding/json" "fmt" "io/ioutil" "log" "net/http" "os" "strconv" "strings" ) //color config var color map[string]interface{} //Parse config file func readConfig() { config, err := os.Open("config.ini") if err != nil { log.Fatalln(err) } buf := bufio.NewReader(config) line, _ := buf.ReadString('\n') var jsonData interface{} err = json.Unmarshal([]byte(line), &jsonData) if err != nil { log.Fatalln(err) } var ok bool color, ok = jsonData.(map[string]interface{}) if ok == false { log.Fatalln("Parse config file error, it must be a json string!") } for _, c := range color { if c.(float64) > 37 || c.(float64) < 30 { log.Fatalln("Config error!The valid value is 30-37.") } } item := [5]string{"url", "varName", "varType", "varValue", "group"} for _, i := range item { _, has := color[i] if has == false { log.Fatalln("Losing configuration:", i) } } } func main() { var port int = 8888 if len(os.Args) == 1 { fmt.Println("Listening in default port:8888") } else if os.Args[1] == "--help" { fmt.Println("usage: proxy [-p port]") return } else if len(os.Args) != 3 || os.Args[1] != "-p" { log.Fatalln("Error arguments!Just support '-p port'.") } else { port, err := strconv.Atoi(os.Args[2]) if err != nil && port > 65535 || port < 1024 { log.Fatalln("Error port, it should be 1024-65535, default is 8888.") } } readConfig() http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { r.RequestURI = "" resp, err := http.DefaultClient.Do(r) if err != nil { http.NotFound(w, r) return } defer resp.Body.Close() //Get the debugging information form http header caterory := map[string]int{"I": 34, "W": 33, "E": 31} format := "\t \033[%dm-%s\033[%vm %s\033[%vm%s\033[%vm%s\n" debugItem := make(map[string]map[string]interface{}) debugItemIndex := make([]string, 0, 5) var jsonData interface{} v, okDebugItem := resp.Header["Proxy_debug_item_count"] if okDebugItem { count, _ := strconv.Atoi(v[0]) for i := 1; i <= count; i++ { index := "Proxy_debug_item_" + strconv.Itoa(i) vv, ok := resp.Header[index] if ok { err = json.Unmarshal([]byte(vv[0]), &jsonData) if err != nil { continue } data, ok := jsonData.(map[string]interface{}) if ok == false { continue } debugItemIndex = append(debugItemIndex, index) debugItem[index] = data } } } debugGroup := make(map[string]interface{}) debugGroupIndex := make([]string, 0, 5) v, okDebugGroup := resp.Header["Proxy_debug_group_count"] if okDebugGroup { count, _ := strconv.Atoi(v[0]) for i := 1; i maxLenName { maxLenName = len(v) } v = vm["type"].(string) if len(v) > maxLenType { maxLenType = len(v) } } for _, i := range debugItemIndex { n := debugItem[i]["name"].(string) t := debugItem[i]["type"].(string) c := debugItem[i]["category"].(string) fmt.Printf( format, caterory[c], c, color["varName"], n+strings.Repeat(" ", maxLenName-len(n)+1), color["varType"], t+strings.Repeat(" ", maxLenType-len(t)+1), color["varValue"], strings.Replace(fmt.Sprint(debugItem[i]["value"]), "map", "", 1)) } } if okDebugGroup { if okDebugItem == false { fmt.Printf("\033[%vm%v\n", color["url"], r.URL) } maxLenName := make([]int, len(debugGroupIndex)) maxLenType := make([]int, len(debugGroupIndex)) k := 0 for _, vm := range debugGroup { for _, vv := range vm.([]interface{}) { vk, ok := vv.(map[string]interface{}) if ok == false { continue } v := vk["name"].(string) if len(v) > maxLenName[k] { maxLenName[k] = len(v) } v = vk["type"].(string) if len(v) > maxLenType[k] { maxLenType[k] = len(v) } } k++ } k = 0 for _, i := range debugGroupIndex { fmt.Printf("\t\033[%vm=Group %v=\n", color["group"], k+1) for _, v := range debugGroup[i].([]interface{}) { vk, ok := v.(map[string]interface{}) if ok == false { continue } n := vk["name"].(string) t := vk["type"].(string) c := vk["category"].(string) fmt.Printf( format, caterory[c], c, color["varName"], n+strings.Repeat(" ", maxLenName[k]-len(n)+1), color["varType"], t+strings.Repeat(" ", maxLenType[k]-len(t)+1), color["varValue"], strings.Replace(fmt.Sprint(vk["value"]), "map", "", 1)) } k++ fmt.Printf("\t\033[%vm=GROUP=\n", color["group"]) } } }) http.ListenAndServe(":"+strconv.Itoa(port), nil) }
3. [图片] screenshot.png
성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.

핫 AI 도구

Undresser.AI Undress
사실적인 누드 사진을 만들기 위한 AI 기반 앱

AI Clothes Remover
사진에서 옷을 제거하는 온라인 AI 도구입니다.

Undress AI Tool
무료로 이미지를 벗다

Clothoff.io
AI 옷 제거제

AI Hentai Generator
AI Hentai를 무료로 생성하십시오.

인기 기사
R.E.P.O. 에너지 결정과 그들이하는 일 (노란색 크리스탈)
3 몇 주 전By尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. 최고의 그래픽 설정
3 몇 주 전By尊渡假赌尊渡假赌尊渡假赌
어 ass 신 크리드 그림자 : 조개 수수께끼 솔루션
1 몇 주 전ByDDD
R.E.P.O. 아무도들을 수없는 경우 오디오를 수정하는 방법
3 몇 주 전By尊渡假赌尊渡假赌尊渡假赌
Atomfall에서 크레인 제어 키 카드를 찾을 수 있습니다
1 몇 주 전ByDDD

뜨거운 도구

SublimeText3 영어 버전
권장 사항: Win 버전, 코드 프롬프트 지원!

SecList
SecLists는 최고의 보안 테스터의 동반자입니다. 보안 평가 시 자주 사용되는 다양한 유형의 목록을 한 곳에 모아 놓은 것입니다. SecLists는 보안 테스터에게 필요할 수 있는 모든 목록을 편리하게 제공하여 보안 테스트를 더욱 효율적이고 생산적으로 만드는 데 도움이 됩니다. 목록 유형에는 사용자 이름, 비밀번호, URL, 퍼징 페이로드, 민감한 데이터 패턴, 웹 셸 등이 포함됩니다. 테스터는 이 저장소를 새로운 테스트 시스템으로 간단히 가져올 수 있으며 필요한 모든 유형의 목록에 액세스할 수 있습니다.

Dreamweaver Mac版
시각적 웹 개발 도구

Eclipse용 SAP NetWeaver 서버 어댑터
Eclipse를 SAP NetWeaver 애플리케이션 서버와 통합합니다.

SublimeText3 Linux 새 버전
SublimeText3 Linux 최신 버전
