Last active
November 18, 2019 07:56
-
-
Save sko00o/f0d028520f91b231934e035fe7b49f54 to your computer and use it in GitHub Desktop.
[Simple http proxy server] #Go
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
import ( | |
"bytes" | |
"encoding/json" | |
"flag" | |
"fmt" | |
"io/ioutil" | |
"log" | |
"net/http" | |
) | |
var ( | |
port string | |
) | |
func init() { | |
// accept command args | |
flag.StringVar(&port, "p", "8998", "listening port") | |
flag.Parse() | |
} | |
func main() { | |
http.HandleFunc("/proxy", proxy) | |
addr := "0.0.0.0:" + port | |
log.Println("listen on", addr) | |
if err := http.ListenAndServe(addr, nil); err != nil { | |
log.Fatal(err) | |
} | |
} | |
type Request struct { | |
// request metod , default is GET | |
Method string `json:"method"` | |
// request URL | |
URL string `json:"url"` | |
// request body content | |
Body []byte `json:"body"` | |
} | |
type Response struct { | |
// status code from target | |
Code int `json:"code"` | |
// data return by target,if not json | |
// then use base64 for output | |
Data interface{} `json:"data,omitempty"` | |
} | |
func proxy(w http.ResponseWriter, r *http.Request) { | |
var resp Response | |
defer func() { | |
w.WriteHeader(http.StatusOK) | |
out, _ := json.Marshal(resp) | |
if _, err := w.Write(out); err != nil { | |
log.Printf("response error: %s", err) | |
} | |
}() | |
var req Request | |
if err := json.NewDecoder(r.Body).Decode(&req); err != nil { | |
resp.Code = http.StatusBadRequest | |
resp.Data = fmt.Sprintf("json decode error: %s", err) | |
return | |
} | |
nReq, err := http.NewRequest(req.Method, req.URL, bytes.NewReader(req.Body)) | |
if err != nil { | |
resp.Code = http.StatusInternalServerError | |
resp.Data = fmt.Sprintf("request error: %s", err) | |
return | |
} | |
nResp, err := http.DefaultClient.Do(nReq) | |
if err != nil { | |
resp.Code = http.StatusInternalServerError | |
resp.Data = fmt.Sprintf("client request error: %s", err) | |
return | |
} | |
data, err := ioutil.ReadAll(nResp.Body) | |
if err != nil { | |
resp.Code = http.StatusInternalServerError | |
resp.Data = fmt.Sprintf("read body error: %s", err) | |
return | |
} | |
resp.Code = nResp.StatusCode | |
jsonMap := make(map[string]interface{}) | |
if err := json.Unmarshal(data, &jsonMap); err == nil { | |
resp.Data = jsonMap | |
} else { | |
resp.Data = data | |
} | |
return | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment