Last active
August 29, 2015 14:19
-
-
Save pokstad/b74b572844d7f9521716 to your computer and use it in GitHub Desktop.
CouchDB Reverse Proxy in 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 ( | |
"net/http" | |
"net/url" | |
"net/http/httputil" | |
"github.com/pokstad/go-couchdb/couchdaemon" | |
"github.com/pokstad/go-couchdb" | |
"time" | |
"sync" | |
) | |
var logger couchdaemon.LogWriter | |
var server_configs = map[string]string{ | |
"username":"username_goes_here", // optional, provide credentials through local.ini | |
"password":"password_goes_here", // optional, provide credentials through local.ini | |
"couchURL":"http://localhost:5984", // optional | |
"static_web_assets":"/www/public", // static files | |
"http_port":":8080", // only root can run port 80 | |
"ssl_port":":4433", // only root can run port 443 | |
"public_key":"/ssl/server.crt", // If you want SSL... | |
"private_key":"/ssl/server.key", // If you want SSL... | |
} | |
func fetchCouchdbConfigs() { | |
fetched_configs, err := couchdaemon.ConfigSection("go_server") | |
if err != nil { | |
logger.Err(err) | |
panic(err) | |
} | |
for k, v := range fetched_configs { | |
// overwrite values in default_configs with ones we received from CouchDB | |
server_configs[k] = v | |
} | |
logger.Debug(server_configs) | |
} | |
func customAPI(rw http.ResponseWriter, req *http.Request) { | |
// your middleware lives here | |
} | |
func main() { | |
couchdaemon.Init(nil) | |
logger = couchdaemon.NewLogWriter() | |
fetchCouchdbConfigs() | |
logger.Debug("Server starting") | |
couchServer, err := couchdb.NewClient(server_configs["couchURL"], nil) | |
if err != nil { | |
logger.Err(err) | |
panic(err) | |
} | |
couchAuth := couchdb.BasicAuth(server_configs["username"], server_configs["password"]) | |
couchServer.SetAuth(couchAuth) | |
mux := http.NewServeMux() | |
// by default, URL's will be mapped to our static assets | |
mux.Handle("/", | |
http.FileServer(http.Dir(server_configs["static_web_assets"]))) | |
// create a reverse proxy to our couch server | |
proxy_url, _ := url.Parse(server_configs["couchURL"]) | |
mux.Handle("/db/", | |
http.StripPrefix("/db/", | |
httputil.NewSingleHostReverseProxy(proxy_url))) | |
mux.HandleFunc("/api", customAPI) | |
http_serv := &http.Server{ | |
Addr: server_configs["http_port"], | |
Handler: mux, | |
ReadTimeout:30*time.Second, // helps kill ghost Goroutines: | |
// http://stackoverflow.com/questions/10971800/golang-http-server-leaving-open-goroutines | |
//ErrorLog: nil, // suppresses errors from stderr | |
} | |
http_ssl_serv := &http.Server{ | |
Addr: server_configs["ssl_port"], | |
Handler: mux, | |
ReadTimeout:30*time.Second, // helps kill ghost Goroutines: | |
// http://stackoverflow.com/questions/10971800/golang-http-server-leaving-open-goroutines | |
//ErrorLog: nil, // suppresses errors from stderr | |
} | |
// In order to run these two forever blocking methods, we need goroutines | |
wg := &sync.WaitGroup{} | |
wg.Add(1) | |
go func() { | |
http_err := http_serv.ListenAndServe() // run forever | |
logger.Debug(http_err) | |
wg.Done() | |
}() | |
wg.Add(1) | |
go func() { | |
ssl_err := http_ssl_serv.ListenAndServeTLS( | |
server_configs["public_key"], | |
server_configs["private_key"], | |
) // run forever | |
logger.Debug(ssl_err) | |
wg.Done() | |
}() | |
wg.Wait() // beyond this line is reached when both servers stop | |
logger.Err("Server closing."); | |
} |
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
; CouchDB Configuration Settings | |
; Custom settings should be made in this file. They will override settings | |
; in default.ini, but unlike changes made to default.ini, this file won't be | |
; overwritten on server upgrade. | |
[couchdb] | |
;max_document_size = 4294967296 ; bytes | |
[httpd] | |
;port = 5984 | |
;bind_address = 127.0.0.1 | |
; Options for the MochiWeb HTTP server. | |
;server_options = [{backlog, 128}, {acceptor_pool_size, 16}] | |
; For more socket options, consult Erlang's module 'inet' man page. | |
;socket_options = [{recbuf, 262144}, {sndbuf, 262144}, {nodelay, true}] | |
; Uncomment next line to trigger basic-auth popup on unauthorized requests. | |
;WWW-Authenticate = Basic realm="administrator" | |
; Uncomment next line to set the configuration modification whitelist. Only | |
; whitelisted values may be changed via the /_config URLs. To allow the admin | |
; to change this value over HTTP, remember to include {httpd,config_whitelist} | |
; itself. Excluding it from the list would require editing this file to update | |
; the whitelist. | |
;config_whitelist = [{httpd,config_whitelist}, {log,level}, {etc,etc}] | |
[query_servers] | |
;nodejs = /usr/local/bin/couchjs-node /path/to/couchdb/share/server/main.js | |
[httpd_global_handlers] | |
;_google = {couch_httpd_proxy, handle_proxy_req, <<"http://www.google.com">>} | |
[couch_httpd_auth] | |
; If you set this to true, you should also uncomment the WWW-Authenticate line | |
; above. If you don't configure a WWW-Authenticate header, CouchDB will send | |
; Basic realm="server" in order to prevent you getting logged out. | |
; require_valid_user = false | |
timeout = 360000 | |
[log] | |
;level = debug | |
[log_level_by_module] | |
; In this section you can specify any of the four log levels 'none', 'info', | |
; 'error' or 'debug' on a per-module basis. See src/*/*.erl for various | |
; modules. | |
;couch_httpd = error | |
[os_daemons] | |
; For any commands listed here, CouchDB will attempt to ensure that | |
; the process remains alive. Daemons should monitor their environment | |
; to know when to exit. This can most easily be accomplished by exiting | |
; when stdin is closed. | |
;foo = /path/to/command -with args | |
go_server = /usr/local/lib/goserver/goserver | |
[daemons] | |
; enable SSL support by uncommenting the following line and supply the PEM's below. | |
; the default ssl port CouchDB listens on is 6984 | |
; httpsd = {couch_httpd, start_link, [https]} | |
[go_server] | |
; go_server configs can go here. Defaults listed below: | |
username = couchdb_username | |
password = couchdb_password | |
couchURL = http://localhost:5984 | |
static_web_assets = /usr/local/lib/goserver/www | |
http_port = :8080 | |
ssl_port = :4433 | |
public_key = /usr/local/lib/goserver/ssl/server.crt | |
private_key = /usr/local/lib/goserver/ssl/server.key | |
[ssl] | |
;cert_file = /full/path/to/server_cert.pem | |
;key_file = /full/path/to/server_key.pem | |
;password = somepassword | |
; set to true to validate peer certificates | |
verify_ssl_certificates = false | |
; Path to file containing PEM encoded CA certificates (trusted | |
; certificates used for verifying a peer certificate). May be omitted if | |
; you do not want to verify the peer. | |
;cacert_file = /full/path/to/cacertf | |
; The verification fun (optional) if not specified, the default | |
; verification fun will be used. | |
;verify_fun = {Module, VerifyFun} | |
; maximum peer certificate depth | |
ssl_certificate_max_depth = 1 | |
; To enable Virtual Hosts in CouchDB, add a vhost = path directive. All requests to | |
; the Virual Host will be redirected to the path. In the example below all requests | |
; to http://example.com/ are redirected to /database. | |
; If you run CouchDB on a specific port, include the port number in the vhost: | |
; example.com:5984 = /database | |
[vhosts] | |
;example.com = /database/ | |
[update_notification] | |
;unique notifier name=/full/path/to/exe -with "cmd line arg" | |
; To create an admin account uncomment the '[admins]' section below and add a | |
; line in the format 'username = password'. When you next start CouchDB, it | |
; will change the password to a hash (so that your passwords don't linger | |
; around in plain-text files). You can add more admin accounts with more | |
; 'username = password' lines. Don't forget to restart CouchDB after | |
; changing this. | |
[admins] | |
;admin = mysecretpassword |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment