via

Simple pubsub server inspired by https://patchbay.pub/
git clone https://git.ce9e.org/via.git

commit
d5c79be01cf794d09180b33110aa640a29050e7f
parent
5a2f503637a8702b3c7a24ab8162609cb306ac06
Author
Tobias Bengfort <tobias.bengfort@posteo.de>
Date
2020-10-15 07:51
Revert "add file storage"

This reverts commit 0dd16c8ba2b9370902c655e299e807de0f3eca72.

Diffstat

M README.md 26 ++++++++++++++------------
M via.go 80 ++++++-------------------------------------------------------

2 files changed, 21 insertions, 85 deletions


diff --git a/README.md b/README.md

@@ -1,9 +1,8 @@
    1    -1 # Via - Simple generic HTTP server for messages and storage
   -1     1 # Via - Simple pubsub server
    2     2 
    3    -1 This is a minimal but generic server that does two things:
    4    -1 
    5    -1 -	pass messages between clients
    6    -1 -	store data
   -1     3 This is very much inspired by <https://patchbay.pub/> and its clones
   -1     4 [conduit](https://github.com/prologic/conduit) and
   -1     5 [duct](https://github.com/schollz/duct).
    7     6 
    8     7 ## Usage
    9     8 
@@ -19,13 +18,8 @@ Then start sending requests on the client:
   19    18 	# POST a message
   20    19 	curl http://localhost:8001/msg/someid -d somedata
   21    20 
   22    -1 	# Store, get, and delete a document
   23    -1 	curl http://localhost:8001/store/someid -d someid
   24    -1 	curl http://localhost:8001/store/someid
   25    -1 	curl http://localhost:8001/store/someid -X DELETE
   26    -1 
   27    -1 You can also protect your message ID with a password so no one else can listen
   28    -1 to it at the same time:
   -1    21 You can also protect your ID with a password so no one else can listen to
   -1    22 it at the same time:
   29    23 
   30    24 	curl http://localhost:8001/msg/someid:somepassword
   31    25 	curl http://localhost:8001/msg/someid  # 403
@@ -34,3 +28,11 @@ to it at the same time:
   34    28 You should regularly clean up old files:
   35    29 
   36    30 	find {storage_dir} -type f -mtime +7 -delete
   -1    31 
   -1    32 ## Differences to patchbay
   -1    33 
   -1    34 -	no support for MPMC (blocking POST)
   -1    35 -	no support for req/res
   -1    36 -	no support for blocking GET
   -1    37 -	support for [server-sent events](https://developer.mozilla.org/en-US/docs/Web/API/Server-sent_events)
   -1    38 -	support for passwords

diff --git a/via.go b/via.go

@@ -85,12 +85,11 @@ func popChannel(key string, ch chan Msg) {
   85    85 }
   86    86 
   87    87 func getStorePath(key string) string {
   88    -1 	rel := strings.TrimPrefix(key, "/store/")
   89    -1 	hash := base64.URLEncoding.EncodeToString([]byte(rel))
   -1    88 	hash := base64.URLEncoding.EncodeToString([]byte(key))
   90    89 	return path.Join(dir, hash)
   91    90 }
   92    91 
   93    -1 func postMsg(w http.ResponseWriter, r *http.Request) {
   -1    92 func post(w http.ResponseWriter, r *http.Request) {
   94    93 	key, password := splitPassword(r.URL.Path)
   95    94 
   96    95 	if password != "" {
@@ -126,7 +125,7 @@ func postMsg(w http.ResponseWriter, r *http.Request) {
  126   125 	}
  127   126 }
  128   127 
  129    -1 func getMsg(w http.ResponseWriter, r *http.Request) {
   -1   128 func get(w http.ResponseWriter, r *http.Request) {
  130   129 	key, password := splitPassword(r.URL.Path)
  131   130 
  132   131 	ch := make(chan Msg)
@@ -168,79 +167,15 @@ func getMsg(w http.ResponseWriter, r *http.Request) {
  168   167 	}
  169   168 }
  170   169 
  171    -1 func putStore(w http.ResponseWriter, r *http.Request) {
  172    -1 	path := getStorePath(r.URL.Path)
  173    -1 
  174    -1 	content, err := ioutil.ReadAll(r.Body)
  175    -1 	if err != nil {
  176    -1 		log.Println("error reading request body:", err)
  177    -1 		http.Error(w, "Internal Server Error", http.StatusInternalServerError)
  178    -1 		return
  179    -1 	}
  180    -1 
  181    -1 	err = ioutil.WriteFile(path, content, 0644)
  182    -1 	if err != nil {
  183    -1 		log.Println("error writing to file:", err)
  184    -1 		http.Error(w, "Internal Server Error", http.StatusInternalServerError)
  185    -1 		return
  186    -1 	}
  187    -1 }
  188    -1 
  189    -1 func getStore(w http.ResponseWriter, r *http.Request) {
  190    -1 	path := getStorePath(r.URL.Path)
  191    -1 
  192    -1 	content, err := ioutil.ReadFile(path)
  193    -1 	if os.IsNotExist(err) {
  194    -1 		http.Error(w, "Not Found", http.StatusNotFound)
  195    -1 		return
  196    -1 	} else if err != nil {
  197    -1 		log.Println("error reading from file:", err)
  198    -1 		http.Error(w, "Internal Server Error", http.StatusInternalServerError)
  199    -1 		return
  200    -1 	}
  201    -1 
  202    -1 	w.Write(content)
  203    -1 }
  204    -1 
  205    -1 func deleteStore(w http.ResponseWriter, r *http.Request) {
  206    -1 	path := getStorePath(r.URL.Path)
  207    -1 
  208    -1 	err := os.Remove(path)
  209    -1 	if os.IsNotExist(err) {
  210    -1 		http.Error(w, "Not Found", http.StatusNotFound)
  211    -1 		return
  212    -1 	} else if err != nil {
  213    -1 		log.Println("error removing file:", err)
  214    -1 		http.Error(w, "Internal Server Error", http.StatusInternalServerError)
  215    -1 		return
  216    -1 	}
  217    -1 }
  218    -1 
  219    -1 func handleMsg(w http.ResponseWriter, r *http.Request) {
   -1   170 func handler(w http.ResponseWriter, r *http.Request) {
  220   171 	if verbose {
  221   172 		log.Println(r.Method, r.URL)
  222   173 	}
  223   174 
  224   175 	if r.Method == http.MethodGet {
  225    -1 		getMsg(w, r)
   -1   176 		get(w, r)
  226   177 	} else if r.Method == http.MethodPost {
  227    -1 		postMsg(w, r)
  228    -1 	} else {
  229    -1 		http.Error(w, "Unsupported Method", http.StatusMethodNotAllowed)
  230    -1 	}
  231    -1 }
  232    -1 
  233    -1 func handleStore(w http.ResponseWriter, r *http.Request) {
  234    -1 	if verbose {
  235    -1 		log.Println(r.Method, r.URL)
  236    -1 	}
  237    -1 
  238    -1 	if r.Method == http.MethodPut || r.Method == http.MethodPost {
  239    -1 		putStore(w, r)
  240    -1 	} else if r.Method == http.MethodGet || r.Method == http.MethodHead {
  241    -1 		getStore(w, r)
  242    -1 	} else if r.Method == http.MethodDelete {
  243    -1 		deleteStore(w, r)
   -1   178 		post(w, r)
  244   179 	} else {
  245   180 		http.Error(w, "Unsupported Method", http.StatusMethodNotAllowed)
  246   181 	}
@@ -261,8 +196,7 @@ func main() {
  261   196 		addr = fmt.Sprintf("localhost:%s", flag.Args()[0])
  262   197 	}
  263   198 
  264    -1 	http.HandleFunc("/msg/", handleMsg)
  265    -1 	http.HandleFunc("/store/", handleStore)
   -1   199 	http.HandleFunc("/msg/", handler)
  266   200 
  267   201 	log.Printf("Serving on http://%s", addr)
  268   202 	log.Fatal(http.ListenAndServe(addr, nil))