update
This commit is contained in:
parent
baa77f4468
commit
b0007f4cfd
BIN
client.exe
Normal file
BIN
client.exe
Normal file
Binary file not shown.
21
http/miss.go
21
http/miss.go
@ -1,21 +0,0 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
func main() {
|
||||
resp, err := http.Get("https://zh.xhamster.com/?ref=porndude")
|
||||
if err != nil {
|
||||
fmt.Println("http get error", err)
|
||||
return
|
||||
}
|
||||
body, err := ioutil.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
fmt.Println("read error", err)
|
||||
return
|
||||
}
|
||||
fmt.Println(string(body))
|
||||
}
|
||||
@ -6,46 +6,49 @@ import (
|
||||
)
|
||||
|
||||
type UClientProxy struct {
|
||||
ServerConn *UPacketConnection
|
||||
serverAddr string
|
||||
clientAddr string
|
||||
}
|
||||
|
||||
func NewClientProxy() *UClientProxy {
|
||||
return &UClientProxy{}
|
||||
func (client *UClientProxy) NewClientConnection() *PacketConnect {
|
||||
conn, err := net.Dial("tcp", client.clientAddr)
|
||||
if err != nil {
|
||||
zlog.Infof("connect local client error: %s %s", err.Error(), client.clientAddr)
|
||||
return nil
|
||||
}
|
||||
return NewPacketConnect(conn, "local")
|
||||
}
|
||||
func (client *UClientProxy) NewTcpConnection(id uint32) *PacketConnect {
|
||||
conn, err := net.Dial("tcp", client.serverAddr)
|
||||
if err != nil {
|
||||
zlog.Infof("connect server error: %s", err.Error())
|
||||
}
|
||||
remote := NewPacketConnect(conn, "remote")
|
||||
remote.WriteHeader(id)
|
||||
if id == RemoteID {
|
||||
return remote
|
||||
}
|
||||
local := client.NewClientConnection()
|
||||
if local == nil {
|
||||
err = remote.Close()
|
||||
return nil
|
||||
}
|
||||
go local.Forward(remote, 0)
|
||||
go remote.Forward(local, 0)
|
||||
return nil
|
||||
}
|
||||
func (client *UClientProxy) ServeTCP(serverAddr string, clientAddr string) error {
|
||||
conn, err := net.Dial("tcp", serverAddr)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
zlog.Infof("connect server %s", serverAddr)
|
||||
client.ServerConn = NewPacketConnection(conn)
|
||||
_, err = client.ServerConn.Write([]byte("anki"))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
client.serverAddr = serverAddr
|
||||
client.clientAddr = clientAddr
|
||||
RemoteConn := client.NewTcpConnection(RemoteID)
|
||||
zlog.Infof("connect to server %s", RemoteConn.Name())
|
||||
for {
|
||||
data := make([]byte, 4)
|
||||
_, err := client.ServerConn.Read(data, 0, 4)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if string(data) != "anki" {
|
||||
data := RemoteConn.ReadHeader()
|
||||
if string(data[:4]) != "anki" {
|
||||
zlog.Error("rcv package error:", data)
|
||||
client.ServerConn.Clear()
|
||||
continue
|
||||
}
|
||||
conn, err := net.Dial("tcp", clientAddr)
|
||||
if err != nil {
|
||||
zlog.Error("connect local anki error: ", err.Error(), clientAddr)
|
||||
client.ServerConn.ForwardError(err)
|
||||
continue
|
||||
}
|
||||
pc := NewPacketConnection(conn)
|
||||
client.ServerConn.Forward(pc)
|
||||
pc.Forward(client.ServerConn)
|
||||
err = pc.Close()
|
||||
if err != nil {
|
||||
zlog.Error("close local anki error: ", err.Error())
|
||||
}
|
||||
id := packetEndian.Uint32(data[4:])
|
||||
go client.NewTcpConnection(id)
|
||||
}
|
||||
}
|
||||
|
||||
87
proxy/packet_connect.go
Normal file
87
proxy/packet_connect.go
Normal file
@ -0,0 +1,87 @@
|
||||
package proxy
|
||||
|
||||
import (
|
||||
"encoding/binary"
|
||||
"net"
|
||||
"strconv"
|
||||
"time"
|
||||
)
|
||||
|
||||
var (
|
||||
packetEndian = binary.LittleEndian
|
||||
RemoteID uint32 = 1
|
||||
sid = RemoteID
|
||||
maxSid uint32 = 1024 * 1024
|
||||
HeaderSize = 16
|
||||
Magic = "anki"
|
||||
InitBuf = func() []byte {
|
||||
buf := make([]byte, HeaderSize)
|
||||
copy(buf[:len(Magic)], Magic)
|
||||
return buf
|
||||
}()
|
||||
)
|
||||
|
||||
func IncID() uint32 {
|
||||
if sid > maxSid {
|
||||
sid = RemoteID
|
||||
}
|
||||
sid++
|
||||
return sid
|
||||
}
|
||||
|
||||
type PacketConnect struct {
|
||||
net.Conn
|
||||
header []byte
|
||||
id uint32
|
||||
readErr error
|
||||
writeErr error
|
||||
name string
|
||||
}
|
||||
|
||||
func NewPacketConnect(conn net.Conn, name string) *PacketConnect {
|
||||
pc := &PacketConnect{Conn: conn, header: make([]byte, HeaderSize)}
|
||||
pc.SetRemote(name, 0)
|
||||
copy(pc.header, InitBuf)
|
||||
return pc
|
||||
}
|
||||
func (pc *PacketConnect) Name() string {
|
||||
return pc.name
|
||||
}
|
||||
func (pc *PacketConnect) SetRemote(name string, id uint32) {
|
||||
pc.id = id
|
||||
pc.name = "(" + name + ")" + strconv.Itoa(int(id)) + "::" + pc.RemoteAddr().String()
|
||||
}
|
||||
|
||||
func (pc *PacketConnect) Write(data []byte) int {
|
||||
n, err := pc.Conn.Write(data)
|
||||
pc.writeErr = err
|
||||
return n
|
||||
}
|
||||
func (pc *PacketConnect) Read(data []byte) int {
|
||||
n, err := pc.Conn.Read(data)
|
||||
pc.readErr = err
|
||||
return n
|
||||
}
|
||||
func (pc *PacketConnect) ReadHeader() []byte {
|
||||
pc.Read(pc.header)
|
||||
return pc.header
|
||||
}
|
||||
func (pc *PacketConnect) WriteHeader(id uint32) {
|
||||
packetEndian.PutUint32(pc.header[4:8], id)
|
||||
pc.Write(pc.header)
|
||||
}
|
||||
func (pc *PacketConnect) Forward(dst *PacketConnect, rn int) {
|
||||
if rn > 0 {
|
||||
dst.Write(pc.header[:rn])
|
||||
}
|
||||
defer func() {
|
||||
_ = pc.Close()
|
||||
}()
|
||||
data := make([]byte, 1024)
|
||||
for pc.readErr == nil && dst.writeErr == nil {
|
||||
_ = pc.SetReadDeadline(time.Now().Add(time.Second))
|
||||
n := pc.Read(data)
|
||||
rn += n
|
||||
dst.Write(data[:n])
|
||||
}
|
||||
}
|
||||
@ -1,85 +0,0 @@
|
||||
package proxy
|
||||
|
||||
import (
|
||||
"net"
|
||||
"zproxy/zlog"
|
||||
)
|
||||
|
||||
type UPacketConnection struct {
|
||||
*UHttpRequest
|
||||
}
|
||||
|
||||
// 创建连接的方法
|
||||
func NewPacketConnection(conn net.Conn) *UPacketConnection {
|
||||
//初始化Conn属性
|
||||
c := &UPacketConnection{
|
||||
UHttpRequest: NewHttpRequest(conn),
|
||||
}
|
||||
return c
|
||||
}
|
||||
func (pc *UPacketConnection) Forward(target *UPacketConnection) {
|
||||
pc.DataSize = 0
|
||||
pc.IsLoadHeader = false
|
||||
for !pc.IsLoadHeader {
|
||||
data, err := pc.ReadLine()
|
||||
if err != nil {
|
||||
zlog.Error("read header line error: ", err.Error())
|
||||
return
|
||||
}
|
||||
_, err = target.Write(data)
|
||||
if err != nil {
|
||||
zlog.Error("write header line error: ", err.Error())
|
||||
return
|
||||
}
|
||||
}
|
||||
if pc.DataSize == 0 {
|
||||
return
|
||||
}
|
||||
data := make([]byte, 1024)
|
||||
for pc.DataSize > 0 {
|
||||
size := min(pc.DataSize, 1024)
|
||||
n, err := pc.Read(data, 0, size)
|
||||
if err != nil {
|
||||
zlog.Error("read body error: ", err.Error())
|
||||
return
|
||||
}
|
||||
pc.DataSize -= n
|
||||
zlog.Infof("read body %d %s", n, data[:n])
|
||||
_, err = target.Write(data[:n])
|
||||
if err != nil {
|
||||
zlog.Error("write body error: ", err.Error())
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
func (pc *UPacketConnection) Close() error {
|
||||
err := pc.Conn.Close()
|
||||
return err
|
||||
}
|
||||
func (pc *UPacketConnection) ForwardError(err error) {
|
||||
pc.DataSize = 0
|
||||
pc.IsLoadHeader = false
|
||||
zlog.Infof("forward error: ", err.Error())
|
||||
for !pc.IsLoadHeader {
|
||||
_, err := pc.ReadLine()
|
||||
if err != nil {
|
||||
zlog.Error("read header line error: ", err.Error())
|
||||
return
|
||||
}
|
||||
}
|
||||
for pc.DataSize > 0 {
|
||||
data := make([]byte, 1024)
|
||||
size := min(pc.DataSize, 1024)
|
||||
n, err := pc.Read(data, 0, size)
|
||||
if err != nil {
|
||||
zlog.Error("Read body error: ", err.Error())
|
||||
return
|
||||
}
|
||||
pc.DataSize -= n
|
||||
}
|
||||
err = pc.WriteError(err)
|
||||
if err != nil {
|
||||
zlog.Error("write error http error: ", err.Error())
|
||||
return
|
||||
}
|
||||
}
|
||||
@ -1,91 +0,0 @@
|
||||
package proxy
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"io"
|
||||
)
|
||||
|
||||
func min(a int, b int) int {
|
||||
if a < b {
|
||||
return a
|
||||
}
|
||||
return b
|
||||
}
|
||||
|
||||
type UReader struct {
|
||||
io io.Reader
|
||||
buf []byte
|
||||
r, w int
|
||||
err error
|
||||
}
|
||||
|
||||
func NewReader(io io.Reader) *UReader {
|
||||
return &UReader{
|
||||
io: io,
|
||||
buf: make([]byte, 4096),
|
||||
r: 0,
|
||||
w: 0,
|
||||
}
|
||||
}
|
||||
func (b *UReader) Read(data []byte, s int, e int) (int, error) {
|
||||
n := e - s
|
||||
rn := 0
|
||||
for rn < n {
|
||||
d := min(b.w-b.r, n-rn)
|
||||
if d > 0 {
|
||||
copy(data[s+rn:s+rn+d], b.buf[b.r:b.r+d])
|
||||
b.r += d
|
||||
rn += d
|
||||
if rn >= n {
|
||||
break
|
||||
}
|
||||
}
|
||||
err := b.fill()
|
||||
if err != nil {
|
||||
return rn, err
|
||||
}
|
||||
}
|
||||
return rn, nil
|
||||
|
||||
}
|
||||
func (b *UReader) ReadLine() ([]byte, error) {
|
||||
line, err := b.ReadSlice('\n')
|
||||
return line, err
|
||||
}
|
||||
func (b *UReader) ReadSlice(delim byte) ([]byte, error) {
|
||||
s := 0 // search start index
|
||||
for {
|
||||
// Search buffer.
|
||||
if i := bytes.IndexByte(b.buf[b.r+s:b.w], delim); i >= 0 {
|
||||
i += s + 1
|
||||
b.r += i
|
||||
return b.buf[b.r-i : b.r], nil
|
||||
}
|
||||
err := b.fill()
|
||||
if err != nil {
|
||||
return b.buf[b.r:], err
|
||||
}
|
||||
}
|
||||
}
|
||||
func (b *UReader) fill() error {
|
||||
d := b.w - b.r
|
||||
if d >= len(b.buf) {
|
||||
b.r = 0
|
||||
b.w = 0
|
||||
return ErrBufferFull
|
||||
}
|
||||
// Slide existing data to beginning.
|
||||
if b.r > 0 {
|
||||
copy(b.buf, b.buf[b.r:b.w])
|
||||
b.w -= b.r
|
||||
b.r = 0
|
||||
}
|
||||
// Read new data: try a limited number of times.
|
||||
n, err := b.io.Read(b.buf[b.w:])
|
||||
b.w += n
|
||||
return err
|
||||
}
|
||||
func (b *UReader) Clear() {
|
||||
b.r = 0
|
||||
b.w = 0
|
||||
}
|
||||
@ -1,80 +0,0 @@
|
||||
package proxy
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"net"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
type UHttpRequest struct {
|
||||
Conn net.Conn
|
||||
io *UReader
|
||||
IsLoadHeader bool
|
||||
DataSize int
|
||||
}
|
||||
|
||||
func NewHttpRequest(conn net.Conn) *UHttpRequest {
|
||||
return &UHttpRequest{
|
||||
Conn: conn,
|
||||
io: NewReader(conn),
|
||||
IsLoadHeader: false,
|
||||
DataSize: 0,
|
||||
}
|
||||
}
|
||||
func (req *UHttpRequest) ReadLine() ([]byte, error) {
|
||||
line, err := req.io.ReadLine()
|
||||
if err != nil {
|
||||
return line, err
|
||||
}
|
||||
if !req.IsLoadHeader && bytes.Equal(line, []byte("\r\n")) {
|
||||
req.IsLoadHeader = true
|
||||
}
|
||||
if !req.IsLoadHeader {
|
||||
k, v, ok := bytes.Cut(line, []byte(":"))
|
||||
if !ok {
|
||||
return line, err
|
||||
}
|
||||
if bytes.Equal(k, []byte("Content-Length")) {
|
||||
nv := strings.Trim(string(v), " \r\n")
|
||||
n, err := strconv.ParseUint(nv, 10, 63)
|
||||
if err != nil {
|
||||
return line, err
|
||||
}
|
||||
req.DataSize = int(n)
|
||||
}
|
||||
}
|
||||
return line, err
|
||||
}
|
||||
func (req *UHttpRequest) Read(data []byte, s int, e int) (int, error) {
|
||||
return req.io.Read(data, s, e)
|
||||
}
|
||||
func (req *UHttpRequest) Write(data []byte) (int, error) {
|
||||
return req.Conn.Write(data)
|
||||
}
|
||||
func (req *UHttpRequest) WriteError(err error) error {
|
||||
return req.WriteHttp([]byte("HTTP/1.1 200 OK\r\n"), []byte(err.Error()))
|
||||
}
|
||||
func (req *UHttpRequest) WriteHttp(header []byte, data []byte) error {
|
||||
_, err := req.Write(header)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
var bufBody bytes.Buffer
|
||||
bufBody.WriteString("{\n \"error\" : \"")
|
||||
bufBody.WriteString(string(data))
|
||||
bufBody.WriteString("\"\n}")
|
||||
var bufWrap bytes.Buffer
|
||||
bufWrap.WriteString("Content-Length:")
|
||||
bufWrap.WriteString(strconv.Itoa(bufBody.Len()))
|
||||
bufWrap.WriteString("\r\n\r\n")
|
||||
_, err = req.Write(bufWrap.Bytes())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
_, err = req.Write(bufBody.Bytes())
|
||||
return err
|
||||
}
|
||||
func (req *UHttpRequest) Clear() {
|
||||
req.io.Clear()
|
||||
}
|
||||
@ -6,66 +6,85 @@ import (
|
||||
)
|
||||
|
||||
type UServerProxy struct {
|
||||
AnkiConn *UPacketConnection
|
||||
RemoteMap map[uint32]*PacketConnect
|
||||
ClientMap map[uint32]*PacketConnect
|
||||
RemoteConn *PacketConnect
|
||||
MessageQueue chan uint32
|
||||
}
|
||||
|
||||
func NewServerProxy() *UServerProxy {
|
||||
return &UServerProxy{}
|
||||
return &UServerProxy{
|
||||
RemoteMap: make(map[uint32]*PacketConnect),
|
||||
ClientMap: make(map[uint32]*PacketConnect),
|
||||
MessageQueue: make(chan uint32, 32),
|
||||
}
|
||||
}
|
||||
func (server *UServerProxy) NewTcpConnection(client *UPacketConnection) {
|
||||
defer func() {
|
||||
if client == server.AnkiConn {
|
||||
func (server *UServerProxy) NewTcpConnection(client *PacketConnect) {
|
||||
data := client.ReadHeader()
|
||||
if string(data[:4]) == "anki" {
|
||||
id := packetEndian.Uint32(data[4:8])
|
||||
client.SetRemote("remote", id)
|
||||
if id == RemoteID {
|
||||
if server.RemoteConn != nil && server.RemoteConn != client {
|
||||
_ = server.RemoteConn.Close()
|
||||
}
|
||||
server.RemoteConn = client
|
||||
zlog.Infof("rcv %d %s", id, client.Name())
|
||||
} else {
|
||||
server.RemoteMap[id] = client
|
||||
server.MessageQueue <- id
|
||||
}
|
||||
return
|
||||
}
|
||||
err := client.Close()
|
||||
if err != nil {
|
||||
zlog.Error("close client error: ", err)
|
||||
if server.RemoteConn == nil {
|
||||
return
|
||||
}
|
||||
id := IncID()
|
||||
server.RemoteConn.WriteHeader(id)
|
||||
server.ClientMap[id] = client
|
||||
zlog.Infof("%d %s", id, data)
|
||||
}
|
||||
func (server *UServerProxy) MessageLoop() {
|
||||
for {
|
||||
select {
|
||||
case mid := <-server.MessageQueue:
|
||||
remote := server.RemoteMap[mid]
|
||||
client := server.ClientMap[mid]
|
||||
if client == nil || remote == nil {
|
||||
server.RemoteMap[mid] = nil
|
||||
server.ClientMap[mid] = nil
|
||||
continue
|
||||
}
|
||||
go func() {
|
||||
client.Forward(remote, HeaderSize)
|
||||
server.ClientMap[mid] = nil
|
||||
}()
|
||||
go func() {
|
||||
remote.Forward(client, 0)
|
||||
server.RemoteMap[mid] = nil
|
||||
}()
|
||||
data := []byte("anki0000")
|
||||
_, err := client.Read(data, 4, 8)
|
||||
if err != nil {
|
||||
zlog.Error("read client error: ", client.Conn.RemoteAddr(), err.Error())
|
||||
return
|
||||
}
|
||||
zlog.Infof("new client %s %s", client.Conn.RemoteAddr(), data[4:])
|
||||
if string(data[4:]) == "anki" {
|
||||
server.AnkiConn = client
|
||||
return
|
||||
}
|
||||
if server.AnkiConn == nil {
|
||||
client.ForwardError(ErrNoAnkiProxy)
|
||||
return
|
||||
}
|
||||
_, err = server.AnkiConn.Write(data)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
client.Forward(server.AnkiConn)
|
||||
server.AnkiConn.Forward(client)
|
||||
}
|
||||
func (server *UServerProxy) ServeTCP(listenAddr string) error {
|
||||
// listenAddr 只能填端口号
|
||||
ln, err := net.Listen("tcp", listenAddr)
|
||||
if err != nil {
|
||||
zlog.Error("listen server error: ", err.Error(), listenAddr)
|
||||
return err
|
||||
zlog.Error("listen error:", err.Error())
|
||||
}
|
||||
zlog.Infof("listen server %s", listenAddr)
|
||||
zlog.Infof("listen %s", ln.Addr())
|
||||
defer func(ln net.Listener) {
|
||||
err := ln.Close()
|
||||
if err != nil {
|
||||
zlog.Error("close listen server error: ", err.Error(), listenAddr)
|
||||
zlog.Error("close client error: ", err.Error())
|
||||
}
|
||||
}(ln)
|
||||
go server.MessageLoop()
|
||||
for {
|
||||
conn, err := ln.Accept()
|
||||
if err != nil {
|
||||
if IsTimeoutError(err) {
|
||||
continue
|
||||
}
|
||||
return err
|
||||
}
|
||||
go server.NewTcpConnection(NewPacketConnection(conn))
|
||||
server.NewTcpConnection(NewPacketConnect(conn, "client"))
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,37 +0,0 @@
|
||||
package proxy
|
||||
|
||||
type timeoutError interface {
|
||||
Timeout() bool // Is it a timeout error
|
||||
}
|
||||
|
||||
// fundamental is an error that has a message and a stack, but no caller.
|
||||
type errors struct {
|
||||
msg string
|
||||
}
|
||||
|
||||
func (e errors) Error() string {
|
||||
return e.msg
|
||||
}
|
||||
|
||||
func NewError(msg string) error {
|
||||
return errors{msg: msg}
|
||||
}
|
||||
|
||||
var (
|
||||
ErrBufferFull = NewError("read: buffer full")
|
||||
ErrNoAnkiProxy = NewError("anki: no client proxy connect")
|
||||
)
|
||||
var (
|
||||
ServerAddr = ":8765"
|
||||
RemoteServerAddr = "175.24.226.114" + ServerAddr
|
||||
ClientAddr = "127.0.0.1:8765"
|
||||
)
|
||||
|
||||
// IsTimeoutError checks if the error is a timeout error
|
||||
func IsTimeoutError(err error) bool {
|
||||
if err == nil {
|
||||
return false
|
||||
}
|
||||
ne, ok := err.(timeoutError)
|
||||
return ok && ne.Timeout()
|
||||
}
|
||||
Binary file not shown.
Binary file not shown.
@ -1,155 +0,0 @@
|
||||
{
|
||||
"cells": [
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 13,
|
||||
"id": "1664172b",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"from http2 import *\n",
|
||||
"class AnkiClient(Http):\n",
|
||||
" def __init__(self):\n",
|
||||
" Http.__init__(self)\n",
|
||||
" self.url = 'http://127.0.0.1:8764'\n",
|
||||
" self.version = None\n",
|
||||
" def api(self, data):\n",
|
||||
" print(data)\n",
|
||||
" data = json.dumps(data)\n",
|
||||
" res = self._post(self.url, data)\n",
|
||||
" return res\n",
|
||||
" def make_version(self):\n",
|
||||
" self.version = self.api({\"action\":\"version\"})\n",
|
||||
" return self.version\n",
|
||||
" def deckNames(self):\n",
|
||||
" return self.api({\"action\":\"deckNames\"})\n",
|
||||
" def modelNames(self):\n",
|
||||
" return self.api({\"action\":\"modelNames\"})\n",
|
||||
" def modelFieldNames(self, modelName):\n",
|
||||
" return self.api({\"action\":\"modelFieldNames\", \"params\" :{\"modelName\" : modelName}})\n",
|
||||
" def addNote(self, note):\n",
|
||||
" return self.api({\"action\":\"addNote\", \"params\" : {\"note\": note}})"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 14,
|
||||
"id": "ee987c62",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"anki = AnkiClient()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 16,
|
||||
"id": "58e77a6b",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"{'action': 'deckNames'}\n",
|
||||
"_post http://127.0.0.1:8764\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"b'[\"Git\", \"\\\\u53e5\\\\u7d20\", \"\\\\u793a\\\\u4f8b\\\\u724c\\\\u7ec4\", \"\\\\u7cfb\\\\u7edf\\\\u9ed8\\\\u8ba4\", \"\\\\u82f1\\\\u8bed\", \"\\\\u8d56\\\\u4e16\\\\u96c4\\\\u97f3\\\\u6807\", \"\\\\u97f3\\\\u6807\"]'"
|
||||
]
|
||||
},
|
||||
"execution_count": 16,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"t = anki.deckNames()\n",
|
||||
"t"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 18,
|
||||
"id": "c3b5b237",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"b'{\\n error = \"anki: no client proxy connect\"\\n}'"
|
||||
]
|
||||
},
|
||||
"execution_count": 18,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"t"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 15,
|
||||
"id": "53bd0e19",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"b = b'{\\n error = \"anki: no client proxy connect\"\\n}'"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 16,
|
||||
"id": "9d89217c",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"{\n",
|
||||
" error = \"anki: no client proxy connect\"\n",
|
||||
"}\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"print(b.decode())"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "203e9f90",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": []
|
||||
}
|
||||
],
|
||||
"metadata": {
|
||||
"kernelspec": {
|
||||
"display_name": "Python 3 (ipykernel)",
|
||||
"language": "python",
|
||||
"name": "python3"
|
||||
},
|
||||
"language_info": {
|
||||
"codemirror_mode": {
|
||||
"name": "ipython",
|
||||
"version": 3
|
||||
},
|
||||
"file_extension": ".py",
|
||||
"mimetype": "text/x-python",
|
||||
"name": "python",
|
||||
"nbconvert_exporter": "python",
|
||||
"pygments_lexer": "ipython3",
|
||||
"version": "3.9.12"
|
||||
}
|
||||
},
|
||||
"nbformat": 4,
|
||||
"nbformat_minor": 5
|
||||
}
|
||||
@ -1,84 +0,0 @@
|
||||
import inspect
|
||||
import json, requests , zlib
|
||||
from functools import wraps
|
||||
from http.cookiejar import LWPCookieJar
|
||||
import http.cookiejar as cookielib
|
||||
default_headers = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit\
|
||||
/537.36 (KHTML, like Gecko) Chrome/54.0.2840.99 Safari/537.36"}
|
||||
class Session(requests.Session):
|
||||
def __init__(self, headers={}, cookie_file=None):
|
||||
requests.Session.__init__(self)
|
||||
if cookie_file:
|
||||
self.cookies = LWPCookieJar(filename = cookie_file)
|
||||
self.cookies.load(ignore_discard = True)
|
||||
self.update(headers)
|
||||
self.auth = ('user', 'pass')
|
||||
def save(self, filename = None):
|
||||
self.cookies.save()
|
||||
def update(self, headers):
|
||||
self.headers.update(headers)
|
||||
def http_error(code):
|
||||
def _with(func):
|
||||
@wraps(func)
|
||||
def _deco(self, url):
|
||||
return func(self, url)
|
||||
_deco.__error_code__ = code
|
||||
return _deco
|
||||
return _with
|
||||
class Http():
|
||||
def __init__(self, headers = default_headers, session = None):
|
||||
session = session or Session()
|
||||
session.update(headers)
|
||||
self.session = session
|
||||
self._type = 'str'
|
||||
self._error_dict = self._get_error_dict()
|
||||
def _gets(self, url, data = None):
|
||||
res = self.session.get(url, params = data)
|
||||
self._error(res, url)
|
||||
return self._res_data(res, self._type)
|
||||
def _posts(self, url, data = None):
|
||||
res = self.session.get(url, params = data)
|
||||
self._error(res, url)
|
||||
return self._res_data(res, self._type)
|
||||
def _get(self, url, data = None):
|
||||
print("_get", url)
|
||||
res = requests.get(url, params = data, headers = self.session.headers)
|
||||
self._error(res, url)
|
||||
return self._res_data(res, self._type)
|
||||
def _post(self, url, data):
|
||||
print("_post", url)
|
||||
res = requests.get(url, data = data, headers = self.session.headers)
|
||||
self._error(res, url)
|
||||
return self._res_data(res, self._type)
|
||||
def _get_error_dict(self):
|
||||
error_dict = {}
|
||||
methods = inspect.getmembers(self, predicate=inspect.ismethod)
|
||||
for method in methods:
|
||||
error_code = getattr(method[1], '__error_code__', None)
|
||||
if error_code:
|
||||
error_dict[error_code] = method[1]
|
||||
return error_dict
|
||||
def _error(self, res, url):
|
||||
code = res.status_code
|
||||
if code == 200:
|
||||
return
|
||||
print(res.content)
|
||||
if code in self._error_dict:
|
||||
self._error_dict[code](url)
|
||||
return
|
||||
raise RuntimeError(code + '- unknown error ' + url)
|
||||
@http_error(403)
|
||||
def _error_403(self, url):
|
||||
raise RuntimeError('error:403 - Forbidden ' + url)
|
||||
@http_error(404)
|
||||
def _error_404(self, url):
|
||||
raise RuntimeError('error:404 - Not Found ' + url)
|
||||
def _res_data(self, res, _type):
|
||||
# encoding = None
|
||||
# if 'Content-Encoding' in res.headers:
|
||||
# encoding = res.headers['Content-Encoding']
|
||||
# if encoding == 'gzip':
|
||||
# res.content = zlib.decompress(res.content, 16 + zlib.MAX_WBITS)
|
||||
# if _type == 'json':
|
||||
# return json.loads(res.content)
|
||||
return res.content
|
||||
@ -1,64 +0,0 @@
|
||||
{
|
||||
"cells": [
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 1,
|
||||
"id": "3f40720a",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"import requests"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 5,
|
||||
"id": "d2986616",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"<Response [200]>"
|
||||
]
|
||||
},
|
||||
"execution_count": 5,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"requests.get(\"http://localhost:8080/\",data = \"helloworld\")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "7f2dd59b",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": []
|
||||
}
|
||||
],
|
||||
"metadata": {
|
||||
"kernelspec": {
|
||||
"display_name": "Python 3 (ipykernel)",
|
||||
"language": "python",
|
||||
"name": "python3"
|
||||
},
|
||||
"language_info": {
|
||||
"codemirror_mode": {
|
||||
"name": "ipython",
|
||||
"version": 3
|
||||
},
|
||||
"file_extension": ".py",
|
||||
"mimetype": "text/x-python",
|
||||
"name": "python",
|
||||
"nbconvert_exporter": "python",
|
||||
"pygments_lexer": "ipython3",
|
||||
"version": "3.9.12"
|
||||
}
|
||||
},
|
||||
"nbformat": 4,
|
||||
"nbformat_minor": 5
|
||||
}
|
||||
@ -1,14 +1,41 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"flag"
|
||||
"strconv"
|
||||
"zproxy/proxy"
|
||||
"zproxy/zlog"
|
||||
)
|
||||
|
||||
var (
|
||||
//ServerAddr = "127.0.0.1"
|
||||
//ServerPort = 8765
|
||||
|
||||
ServerAddr = "175.24.226.114"
|
||||
ServerPort = 7860
|
||||
|
||||
RemoteAddr = "127.0.0.1"
|
||||
RemotePort = 7860
|
||||
)
|
||||
|
||||
func main() {
|
||||
client := proxy.NewClientProxy()
|
||||
err := client.ServeTCP(proxy.RemoteServerAddr, proxy.ClientAddr)
|
||||
client := &proxy.UClientProxy{}
|
||||
err := client.ServeTCP(ServerAddr+":"+strconv.Itoa(ServerPort), RemoteAddr+":"+strconv.Itoa(RemotePort))
|
||||
if err != nil {
|
||||
zlog.Error("exist client remote proxy: ", err.Error())
|
||||
zlog.Error("exist server proxy: ", err.Error())
|
||||
return
|
||||
}
|
||||
}
|
||||
func init() {
|
||||
_addr := flag.String("addr", ServerAddr, "server addr")
|
||||
_port := flag.Int("port", ServerPort, "listen port")
|
||||
|
||||
remoteAddr := flag.String("remote_addr", RemoteAddr, "server addr")
|
||||
remotePort := flag.Int("remote_port", RemotePort, "listen port")
|
||||
flag.Parse()
|
||||
ServerAddr = *_addr
|
||||
ServerPort = *_port
|
||||
|
||||
RemoteAddr = *remoteAddr
|
||||
RemotePort = *remotePort
|
||||
}
|
||||
|
||||
@ -1,15 +1,30 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"flag"
|
||||
"strconv"
|
||||
"zproxy/proxy"
|
||||
"zproxy/zlog"
|
||||
)
|
||||
|
||||
var (
|
||||
//这里只有本地服务器可以访问,传0.0.0.0或空则支持所有连接
|
||||
ServerAddr = "127.0.0.1"
|
||||
ServerPort = 8765
|
||||
)
|
||||
|
||||
func main() {
|
||||
server := proxy.NewServerProxy()
|
||||
err := server.ServeTCP(proxy.ServerAddr)
|
||||
err := server.ServeTCP(ServerAddr + ":" + strconv.Itoa(ServerPort))
|
||||
if err != nil {
|
||||
zlog.Error("exist server proxy: ", err.Error())
|
||||
return
|
||||
}
|
||||
}
|
||||
func init() {
|
||||
_addr := flag.String("addr", ServerAddr, "server addr")
|
||||
_port := flag.Int("port", ServerPort, "listen port")
|
||||
flag.Parse()
|
||||
ServerAddr = *_addr
|
||||
ServerPort = *_port
|
||||
}
|
||||
|
||||
@ -1,11 +0,0 @@
|
||||
package main
|
||||
|
||||
import "net/http"
|
||||
|
||||
func main() {
|
||||
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
|
||||
w.WriteHeader(200)
|
||||
w.Write([]byte("ok"))
|
||||
})
|
||||
http.ListenAndServe(":8080", nil)
|
||||
}
|
||||
BIN
server.exe
Normal file
BIN
server.exe
Normal file
Binary file not shown.
70
zlog/test
70
zlog/test
@ -1,70 +0,0 @@
|
||||
from .http import *
|
||||
import json,functools
|
||||
class util:
|
||||
def api(func):
|
||||
@functools.wraps(func)
|
||||
def wrapper(self,**kwargs):
|
||||
self._api({"params" : kwargs , "action":func.__name__ })
|
||||
self.res = func(self, **kwargs) or self.res
|
||||
return self.res
|
||||
return wrapper
|
||||
class AnkiClient(Http):
|
||||
util = util
|
||||
def __init__(self, url = None):
|
||||
Http.__init__(self)
|
||||
self.url = url or 'http://127.0.0.1:8765'
|
||||
self._version = None
|
||||
self.res = None
|
||||
def _api(self, data):
|
||||
if self._version and type(self._version) == int:
|
||||
data["version"] = self._version
|
||||
data = json.dumps(data)
|
||||
res = self._post(self.url, data)
|
||||
self.res = json.loads(res)
|
||||
return self.res
|
||||
@util.api
|
||||
def version(self):
|
||||
self._version = self.res
|
||||
pass
|
||||
@util.api
|
||||
def deckNames(self):
|
||||
pass
|
||||
@util.api
|
||||
def modelNames(self):
|
||||
pass
|
||||
@util.api
|
||||
def modelFieldNames(self, modelName = "示例牌组"):
|
||||
pass
|
||||
@util.api
|
||||
def modelFieldDescriptions(self, modelName = "示例牌组"):
|
||||
pass
|
||||
@util.api
|
||||
def modelTemplates(self, modelName = "示例牌组"):
|
||||
pass
|
||||
@util.api
|
||||
def addNote(self, note = {}):
|
||||
pass
|
||||
@util.api
|
||||
def findNotes(self, query = "note:basic"):
|
||||
pass
|
||||
@util.api
|
||||
def updateNote(self, note = {}):
|
||||
pass
|
||||
@util.api
|
||||
def updateNoteTags(self, note = {}, tags = []):
|
||||
pass
|
||||
@util.api
|
||||
def notesInfo(self, notes = []):
|
||||
pass
|
||||
@util.api
|
||||
def findCards(self, query = "deck:示例牌组"):
|
||||
pass
|
||||
@util.api
|
||||
def cardsInfo(self, cards = []):
|
||||
pass
|
||||
@util.api
|
||||
def updateNoteFields(self, note = {}):
|
||||
pass
|
||||
@util.api
|
||||
def createModel(self, modelName = "basic", inOrderFields = {}, cardTemplates = {}, css = None, isCloze = False):
|
||||
pass
|
||||
Loading…
Reference in New Issue
Block a user