1 Provides
(require socks5) | package: socks5 |
procedure
(socks5-connect socks-host socks-port dest-host dest-port [ #:username-password username-password])
→
input-port? output-port? socks-host : string? socks-port : positive-integer? dest-host : string? dest-port : positive-integer? username-password : (cons/c bytes? bytes?) = #f
socks-host is the IP or hostname of the SOCKS5 server to connect to.
dest-host is the IP or hostname of the destination server to connect to via the proxy. If it is a hostname, it will be resolved to an IP address by the proxy server. If this behaviour is undesirable, you can locally resolve the IP and pass it instead of the hostname.
As a limitation of the SOCKS5 protocol, the username and password will be transmitted through the network in cleartext.
Example usage
;establish connection to example.com:80 via the proxy 127.0.0.1:1080 (define-values (in out) (socks5-connect "127.0.0.1" 1080 "example.com" 80)) ;send HTTP request (displayln (string-append "GET / HTTP/1.1\r\n" "Host: example.com\r\n" "Connection: close\r\n\r\n") out) ;send TCP FIN (close-output-port out) ;print the server's response (copy-port in (current-output-port))
Closing ports
Closing ports generally works in a reasonable way.
Just like the ports from tcp-connect, closing the output port means no more data will be sent, and triggers a TCP FIN notice. The SOCKS5 server forwards TCP FIN to the destination.
The destination server can also close its side of the connection at any time by sending TCP FIN, which closes the input port here (trying to read will return eof). After both sides have sent TCP FIN, the connection is considered fully closed.
When used with the HTTP protocol, if the request headers have Connection: close, then the server will close its side of the connection immediately after finishing its response. In order to fully close the connection, simply close the output port. (I suggest doing this immediately after sending the HTTP request.)
If the request headers have Connection: keep-alive, multiple HTTP requests can be sent through the same TCP connection. The server won’t automatically close its side of the connection (unless it gets bored through inactivity). This situation is also simple to deal with: closing the output port will show the server that the requests are over, and it will close its side of the connection too.
Typed Racket definition
(provide socks5-connect) (: socks5-connect (String Positive-Integer String Positive-Integer [#:username-password (Option (Pair Bytes Bytes))] -> (Values Input-Port Output-Port))) (define (socks5-connect socks-host socks-port dest-host dest-port #:username-password [username-password #f]) «socks-connect-body»)
procedure
(make-socks5-proxy socks-host socks-port [ matches? #:username-password username-password]) → proxy? socks-host : string? socks-port : positive-integer? matches? : (url? . -> . boolean?) = (λ (_) #t) username-password : (cons/c bytes? bytes?) = #f
socks-host is the IP or hostname of the SOCKS5 server to connect to.
matches? is a function that takes a URL and returns whether it should be handled by this proxy.
As a limitation of the SOCKS5 protocol, the username and password will be transmitted through the network in cleartext.
(define my-proxy (make-socks5-proxy "127.0.0.1" 1080)) (define my-session (make-session #:proxies (list my-proxy))) (define my-response (session-request my-session "https://example.com")) (response-body my-response)
Typed Racket definition