// 程序的主入口 func main() { flag.Parse() to := new(TcpObj) to.Type = *contentType to.Header = make(map[string]string) // 分析 Header switch { // 从文件读取 case !z.IsBlank(*headerf): str, _ := z.Utf8f(z.Ph(*headerf)) z.JsonFromString(str, &to.Header) // 来自参数 case !z.IsBlank(*header): z.JsonFromString(*header, &to.Header) } // 分析 cookie switch { // 从文件读取 case !z.IsBlank(*cookief): to.Cookie, _ = z.Utf8f(*cookief) // 来自参数 default: to.Cookie = *cookie } // 请求体的内容,考虑 -body 或者 -f to.Body = *body if len(*file) > 0 { f, err := os.Open(z.Ph(*file)) if nil != err { panic(err) } to.File = f } // 分析输出方式 switch *out { case "all": to.OutputRequest = true to.OutputResponse = true case "req": to.OutputRequest = true case "resp": to.OutputResponse = true } // 执行 switch { // 发送 HTTP 请求 case !z.IsBlank(*httpUrl): to.Target = *httpUrl to.DoHttp() // 默认,打印参数说明 default: flag.PrintDefaults() } }
// 生成 HTTP 请求对象,主要是填充头部信息 func (to *TcpObj) createRequestHeader() *http.Request { var req *http.Request if len(to.Body) > 0 || nil != to.File { req, _ = http.NewRequest("POST", "http://"+to.Target, nil) } else { req, _ = http.NewRequest("GET", "http://"+to.Target, nil) } // 计算 Host pos := strings.Index(to.Target, "/") var host string if pos > 0 { host = string(to.Target[:pos]) } else { host = to.Target } pos = strings.Index(host, ":") if pos > 0 { host = string(host[:pos]) } // 填充其他信息 req.Header.Set("Accept", "text/plain,text/html,application/json,application/xml;q=0.9,*/*;q=0.8") req.Header.Set("Accept-Encoding", "gzip,deflate,sdch") req.Header.Set("Accept-Language", "zh-CN,zh;q=0.8") req.Header.Set("Cache-Control", "max-age=0") req.Header.Set("Connection", "keep-alive") req.Header.Set("Host", host) req.Header.Set("User-Agent", user_agents["chrome"]) // 填充自定义头部信息 if len(to.Header) > 0 { for key, val := range to.Header { req.Header.Set(key, val) } } // 填充 Cookie if !z.IsBlank(to.Cookie) { req.Header.Set("Cookie", to.Cookie) } return req }
// 读取解析规则, 传入一个实现了io.Reader的对象即可 func (qb *QWBuilder) LoadRules(reader io.Reader) *QWBuilder { bufreader := bufio.NewReader(reader) var line string var lnum int var err error var rules []*QWordRule = make([]*QWordRule, 0) for true { line, err = bufreader.ReadString('\n') if err == io.EOF { err = nil break } else if err != nil { break } lnum++ z.DebugPrintf("rule %2d : %s", lnum, line) // 忽略空行与注释行 line = strings.TrimSpace(line) if z.IsBlank(line) || strings.HasPrefix(line, "#") { continue } // 解析行信息 if strings.HasPrefix(line, "$") { qwRule := new(QWordRule) // 获得key var fpos int = strings.Index(line, ":") if fpos < 0 { err = errors.New(fmt.Sprintf("invalid rule line %d : %s", lnum, line)) break } qwRule.Key = strings.TrimSpace(line[1:fpos]) // 获得regex var expr string if line[fpos+1] == ':' { // 简要模式 expr = "^(" + strings.TrimSpace(line[fpos+2:]) + ")(.*)$" } else { // 普通模式 expr = strings.TrimSpace(line[fpos+1:]) } regex, regerr := regexp.Compile(expr) if regerr != nil { err = regerr break } qwRule.Regex = regex // 读取下一行,必须存在哟 line, err = bufreader.ReadString('\n') if err == io.EOF { err = errors.New(fmt.Sprintf("rule line(%d) miss next line", lnum)) break } else if err != nil { break } lnum++ z.DebugPrintf("rule %2d : %s", lnum, line) line = strings.TrimSpace(line) spos := strings.Index(line, "=") if z.IsBlank(line) || !strings.HasPrefix(line, "$") || spos < 0 { err = errors.New(fmt.Sprintf("invalid rule line %d : %s", lnum, line)) break } // 获得seg qwRule.Seg = z.Trim(line[:spos]) // 获得type qcType, qcterr := QCType(strings.TrimSpace(line[spos+1:])) if qcterr != nil { err = qcterr break } qwRule.Type = qcType // 加入到rules rules = append(rules, qwRule) } } // 是否有错误 if err != nil { panic(err) } qb.Rules = rules return qb }