Examples, CORS
This commit is contained in:
		
							parent
							
								
									1ab0282101
								
							
						
					
					
						commit
						39574c954b
					
				
					 2 changed files with 68 additions and 2 deletions
				
			
		
							
								
								
									
										53
									
								
								examples/example_eventsource_sse.html
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										53
									
								
								examples/example_eventsource_sse.html
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,53 @@
 | 
				
			||||||
 | 
					<!DOCTYPE html>
 | 
				
			||||||
 | 
					<html lang="en">
 | 
				
			||||||
 | 
					<head>
 | 
				
			||||||
 | 
					    <title>ntfy.sh: EventSource Example</title>
 | 
				
			||||||
 | 
					    <style>
 | 
				
			||||||
 | 
					        body { font-size: 1.2em; line-height: 130%; }
 | 
				
			||||||
 | 
					        #events { font-family: monospace; }
 | 
				
			||||||
 | 
					    </style>
 | 
				
			||||||
 | 
					</head>
 | 
				
			||||||
 | 
					<body>
 | 
				
			||||||
 | 
					<h1>ntfy.sh: EventSource Example</h1>
 | 
				
			||||||
 | 
					<p>
 | 
				
			||||||
 | 
					    This is an example showing how to use <a href="https://ntfy.sh">ntfy.sh</a> with
 | 
				
			||||||
 | 
					    <a href="https://developer.mozilla.org/en-US/docs/Web/API/EventSource">EventSource</a>.<br/>
 | 
				
			||||||
 | 
					</p>
 | 
				
			||||||
 | 
					<button id="publishButton">Send test notification</button>
 | 
				
			||||||
 | 
					<p><b>Log:</b></p>
 | 
				
			||||||
 | 
					<div id="events"></div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<script type="text/javascript">
 | 
				
			||||||
 | 
					    const publishURL = `https://ntfy.sh/example`;
 | 
				
			||||||
 | 
					    const subscribeURL = `https://ntfy.sh/example/sse`;
 | 
				
			||||||
 | 
					    const events = document.getElementById('events');
 | 
				
			||||||
 | 
					    const eventSource = new EventSource(subscribeURL);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Publish button
 | 
				
			||||||
 | 
					    document.getElementById("publishButton").onclick = () => {
 | 
				
			||||||
 | 
					        fetch(publishURL, {
 | 
				
			||||||
 | 
					            method: 'POST', // works with PUT as well, though that sends an OPTIONS request too!
 | 
				
			||||||
 | 
					            body: `It is ${new Date().toString()}. This is a test.`
 | 
				
			||||||
 | 
					        })
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Incoming events
 | 
				
			||||||
 | 
					    eventSource.onopen = () => {
 | 
				
			||||||
 | 
					        let event = document.createElement('div');
 | 
				
			||||||
 | 
					        event.innerHTML = `EventSource connected to ${subscribeURL}`;
 | 
				
			||||||
 | 
					        events.appendChild(event);
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					    eventSource.onerror = (e) => {
 | 
				
			||||||
 | 
					        let event = document.createElement('div');
 | 
				
			||||||
 | 
					        event.innerHTML = `EventSource error: Failed to connect to ${subscribeURL}`;
 | 
				
			||||||
 | 
					        events.appendChild(event);
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					    eventSource.onmessage = (e) => {
 | 
				
			||||||
 | 
					        let event = document.createElement('div');
 | 
				
			||||||
 | 
					        event.innerHTML = e.data;
 | 
				
			||||||
 | 
					        events.appendChild(event);
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					</script>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					</body>
 | 
				
			||||||
 | 
					</html>
 | 
				
			||||||
| 
						 | 
					@ -131,6 +131,8 @@ func (s *Server) handleInternal(w http.ResponseWriter, r *http.Request) error {
 | 
				
			||||||
		return s.handleSubscribeRaw(w, r)
 | 
							return s.handleSubscribeRaw(w, r)
 | 
				
			||||||
	} else if (r.Method == http.MethodPut || r.Method == http.MethodPost) && topicRegex.MatchString(r.URL.Path) {
 | 
						} else if (r.Method == http.MethodPut || r.Method == http.MethodPost) && topicRegex.MatchString(r.URL.Path) {
 | 
				
			||||||
		return s.handlePublishHTTP(w, r)
 | 
							return s.handlePublishHTTP(w, r)
 | 
				
			||||||
 | 
						} else if r.Method == http.MethodOptions {
 | 
				
			||||||
 | 
							return s.handleOptions(w, r)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	return errHTTPNotFound
 | 
						return errHTTPNotFound
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -154,7 +156,11 @@ func (s *Server) handlePublishHTTP(w http.ResponseWriter, r *http.Request) error
 | 
				
			||||||
		Time:    time.Now().UnixMilli(),
 | 
							Time:    time.Now().UnixMilli(),
 | 
				
			||||||
		Message: string(b),
 | 
							Message: string(b),
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	return t.Publish(msg)
 | 
						if err := t.Publish(msg); err != nil {
 | 
				
			||||||
 | 
							return err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						w.Header().Set("Access-Control-Allow-Origin", "*") // CORS, allow cross-origin requests
 | 
				
			||||||
 | 
						return nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (s *Server) handleSubscribeJSON(w http.ResponseWriter, r *http.Request) error {
 | 
					func (s *Server) handleSubscribeJSON(w http.ResponseWriter, r *http.Request) error {
 | 
				
			||||||
| 
						 | 
					@ -169,6 +175,7 @@ func (s *Server) handleSubscribeJSON(w http.ResponseWriter, r *http.Request) err
 | 
				
			||||||
		return nil
 | 
							return nil
 | 
				
			||||||
	})
 | 
						})
 | 
				
			||||||
	defer s.unsubscribe(t, subscriberID)
 | 
						defer s.unsubscribe(t, subscriberID)
 | 
				
			||||||
 | 
						w.Header().Set("Access-Control-Allow-Origin", "*") // CORS, allow cross-origin requests
 | 
				
			||||||
	select {
 | 
						select {
 | 
				
			||||||
	case <-t.ctx.Done():
 | 
						case <-t.ctx.Done():
 | 
				
			||||||
	case <-r.Context().Done():
 | 
						case <-r.Context().Done():
 | 
				
			||||||
| 
						 | 
					@ -194,7 +201,7 @@ func (s *Server) handleSubscribeSSE(w http.ResponseWriter, r *http.Request) erro
 | 
				
			||||||
	})
 | 
						})
 | 
				
			||||||
	defer s.unsubscribe(t, subscriberID)
 | 
						defer s.unsubscribe(t, subscriberID)
 | 
				
			||||||
	w.Header().Set("Content-Type", "text/event-stream")
 | 
						w.Header().Set("Content-Type", "text/event-stream")
 | 
				
			||||||
	w.WriteHeader(http.StatusOK)
 | 
						w.Header().Set("Access-Control-Allow-Origin", "*") // CORS, allow cross-origin requests
 | 
				
			||||||
	if _, err := io.WriteString(w, "event: open\n\n"); err != nil {
 | 
						if _, err := io.WriteString(w, "event: open\n\n"); err != nil {
 | 
				
			||||||
		return err
 | 
							return err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
| 
						 | 
					@ -228,6 +235,12 @@ func (s *Server) handleSubscribeRaw(w http.ResponseWriter, r *http.Request) erro
 | 
				
			||||||
	return nil
 | 
						return nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (s *Server) handleOptions(w http.ResponseWriter, r *http.Request) error {
 | 
				
			||||||
 | 
						w.Header().Set("Access-Control-Allow-Origin", "*") // CORS, allow cross-origin requests
 | 
				
			||||||
 | 
						w.Header().Set("Access-Control-Allow-Methods", "GET, PUT, POST")
 | 
				
			||||||
 | 
						return nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (s *Server) createTopic(id string) *topic {
 | 
					func (s *Server) createTopic(id string) *topic {
 | 
				
			||||||
	s.mu.Lock()
 | 
						s.mu.Lock()
 | 
				
			||||||
	defer s.mu.Unlock()
 | 
						defer s.mu.Unlock()
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue