The reverse proxy function and intranet agent in Go Library

Source: Internet
Author: User
This is a creation in Article, where the information may have evolved or changed.

Look at the reverse proxy library first

type reverseproxy struct {//Director must is a function which modifies//the request into a new request to be sent//using Tra Nsport. Its response are then copied//back to the original client unmodified. Director func (*http. Request)//The transport used to perform proxy requests.//If nil, http. Defaulttransport is used. Transport http.  roundtripper//flushinterval Specifies the flush interval//to flush to the client while copying the//response body.//If Zero, no periodic flushing is done. Flushinterval time. duration//errorlog Specifies an optional logger for errors//this occur when attempting to proxy the request.//If nil, l Ogging goes to OS. Stderr via the log package ' s//standard logger. Errorlog *log. logger//Bufferpool Optionally specifies a buffer pool to//get byte slices for use by IO. CopyBuffer when//Copying HTTP response bodies. Bufferpool Bufferpool} 
Then we look at an example (online copy)

Package Mainimport ("Log", "Net/http" "Net/http/httputil" "Net/url") type handle struct {host Stringport string}func (this * HANDLE) servehttp (w http. Responsewriter, R *http. Request) {remote, err: = URL. Parse ("http://" + This.host + "+" + this.port) if err! = Nil {panic (err)}proxy: = Httputil. Newsinglehostreverseproxy (remote) proxy. Servehttp (W, R)}func StartServer () {//proxy server host and Porth: = &handle{host: "127.0.0.1", Port: "W"}err: = http. Listenandserve (": 8888", h) if err! = Nil {log. Fatalln ("Listenandserve:", err)}}func main () {StartServer ()}

It's easy to use. But I sometimes have a special need. such as intranet agent (want to access the target server in the network), then what should be done? General Direction Agent is the proxy server can actively access the target server, the target server is now in the network, the proxy server can not actively access the target server. Usually our proxy server in the public network (for customers and target server), we let the target server in the intranet to establish a connection with the proxy server, when the customer needs to go through the proxy server to access the target intranet server, then the request through the intranet server and Proxy server pre-established connection to the intranet server.

We have two service programs, one running on the proxy server and one running the network server.

A little modification of the above code becomes the program running on the proxy server:

Package Mainimport ("Log", "Net/http" "Net/http/httputil" "Net/url") var conntype handle struct {}func (this *handle) Servehttp (w http. Responsewriter, R *http. Request) {remote, err: = URL. Parse ("http://127.0.0.1:443") if err! = Nil {panic (err)}proxy: = Httputil. Newsinglehostreverseproxy (remote) var ptransport http. Roundtripper = &http. Transport{proxy:http. Proxyfromenvironment,dial:dial,tlshandshaketimeout:10 * time. Second,expectcontinuetimeout:1 * time. Second,}proxy. Transport = Ptransportproxy.servehttp (w,r)}func startserver () {//accepts an active connection to the intranet server 8088 port L, err: = Net. Listen ("TCP", "0.0.0.0:8088") if err! = Nil {return}go func () {for {conn, err = l.accept ()//loop accepts client and device connection request if err! = Nil {Beego. Error ("Can ' t accept:", err) Return}} ()//Accept Client connection H: = &handle{}err: = http. Listenandserve (": 8888", h) if err! = Nil {log. Fatalln ("Listenandserve:", err)}}func Dial (network, address string) (net. Conn, error) {return Conn, Nil}func main () {StartServer ()}

The specific framework is in this way, the syntax is not necessarily right.

Client code (approximate):

func Proxy ( Local, remote string) {conf: = &tls. CONFIG{INSECURESKIPVERIFY:TRUE,}RP, err: = TLS. Dial ("TCP", Remote, conf) if err! = Nil {Beego. Error ("Can ' t ' Connect:", remote, "ERR:", err) Return}defer util. Closeconn (RP) Config: = &tls. Config{insecureskipverify:true}//Do not make certificate check LP, err: = TLS. Dial ("TCP", local, config) if err! = Nil {Beego. Error ("Can ' t ' Connect:", Other, "ERR:", err) Rp. Close () Return}defer util. CLOSECONN (LP)//buf = Make ([]byte, 1024*1024) Rp. Setreaddeadline (time. time{}) LP. Setreaddeadline (time. time{}) Flag: = Make (chan error) go Transfer (RP, LP, Flag)}func Transfer (A, b net. Conn, Flag chan error) {cp: = Func (R, W net). Conn) {n, err: = Io. Copy (R, W) r.close () W.close () Beego. Debug ("Transfer", N, "bytes between", A.remoteaddr (), "and", B.remoteaddr ()) flag <-Err}go CP (A, B) go CP (b, a)}main () {///Local Service address and proxy Server accept the address of the intranet server connection proxy ("127.0.0.1:443", "192.168.16.110:8088")} 

The above is only the approximate framework for reference

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.