Compare commits
	
		
			2 Commits
		
	
	
		
			8c3ee80b21
			...
			8c8e06b015
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 8c8e06b015 | |||
| d7b6967b6f | 
| @ -2,16 +2,19 @@ body { | |||||||
| 	margin: 0; | 	margin: 0; | ||||||
| 	padding: 0; | 	padding: 0; | ||||||
| 	font-family: sans-serif; | 	font-family: sans-serif; | ||||||
|  | 	font-size: clamp(0.5rem, 2vw, 1rem); | ||||||
| } | } | ||||||
| .xP { | .xP { | ||||||
| 	height: 100vh; |  | ||||||
| 	display: flex; | 	display: flex; | ||||||
| 	flex-direction: column; | 	flex-direction: column; | ||||||
| 	overflow: hidden; | 	overflow: hidden; | ||||||
|  | 	height: 100vh; | ||||||
|  | 	/* https://caniuse.com/viewport-unit-variants */ | ||||||
|  | 	height: 100dvh; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| .title, .status { | .title, .status { | ||||||
| 	padding: .05rem .3rem; | 	padding: .05em .3em; | ||||||
| 	background: #eee; | 	background: #eee; | ||||||
| 
 | 
 | ||||||
| 	position: relative; | 	position: relative; | ||||||
| @ -52,10 +55,11 @@ body { | |||||||
| .list { | .list { | ||||||
| 	overflow-y: auto; | 	overflow-y: auto; | ||||||
| 	border-right: 1px solid #ccc; | 	border-right: 1px solid #ccc; | ||||||
| 	min-width: 10rem; | 	min-width: 10em; | ||||||
|  | 	flex-shrink: 0; | ||||||
| } | } | ||||||
| .item { | .item { | ||||||
| 	padding: .05rem .3rem; | 	padding: .05em .3em; | ||||||
| 	cursor: default; | 	cursor: default; | ||||||
| } | } | ||||||
| .item.highlighted { | .item.highlighted { | ||||||
| @ -89,7 +93,7 @@ body { | |||||||
| 	overflow-y: auto; | 	overflow-y: auto; | ||||||
| } | } | ||||||
| .log { | .log { | ||||||
| 	padding: .1rem .3rem; | 	padding: .1em .3em; | ||||||
| 	font-family: monospace; | 	font-family: monospace; | ||||||
| 	white-space: pre-wrap; | 	white-space: pre-wrap; | ||||||
| 	overflow-y: auto; | 	overflow-y: auto; | ||||||
| @ -99,7 +103,7 @@ body { | |||||||
| 	opacity: 50%; | 	opacity: 50%; | ||||||
| } | } | ||||||
| .date { | .date { | ||||||
| 	padding: .3rem; | 	padding: .3em; | ||||||
| 	grid-column: span 2; | 	grid-column: span 2; | ||||||
| 	font-weight: bold; | 	font-weight: bold; | ||||||
| } | } | ||||||
| @ -109,16 +113,16 @@ body { | |||||||
| 	background: #ff5f00; | 	background: #ff5f00; | ||||||
| } | } | ||||||
| .time { | .time { | ||||||
| 	padding: .1rem .3rem; | 	padding: .1em .3em; | ||||||
| 	background: #f8f8f8; | 	background: #f8f8f8; | ||||||
| 	color: #bbb; | 	color: #bbb; | ||||||
| 	border-right: 1px solid #ccc; | 	border-right: 1px solid #ccc; | ||||||
| } | } | ||||||
| .mark { | .mark { | ||||||
| 	padding-right: .3rem; | 	padding-right: .3em; | ||||||
| 	text-align: center; | 	text-align: center; | ||||||
| 	display: inline-block; | 	display: inline-block; | ||||||
| 	min-width: 2rem; | 	min-width: 2em; | ||||||
| } | } | ||||||
| .mark.error { | .mark.error { | ||||||
| 	color: red; | 	color: red; | ||||||
| @ -133,7 +137,7 @@ body { | |||||||
| 	color: darkred; | 	color: darkred; | ||||||
| } | } | ||||||
| .content { | .content { | ||||||
| 	padding: .1rem .3rem; | 	padding: .1em .3em; | ||||||
| 	white-space: pre-wrap; | 	white-space: pre-wrap; | ||||||
| } | } | ||||||
| .content .b { | .content .b { | ||||||
| @ -154,7 +158,7 @@ body { | |||||||
| 
 | 
 | ||||||
| textarea { | textarea { | ||||||
| 	font: inherit; | 	font: inherit; | ||||||
| 	padding: .05rem .3rem; | 	padding: .05em .3em; | ||||||
| 	margin: 0; | 	margin: 0; | ||||||
| 	border: 2px inset #eee; | 	border: 2px inset #eee; | ||||||
| 	flex-shrink: 0; | 	flex-shrink: 0; | ||||||
|  | |||||||
							
								
								
									
										14
									
								
								xP/xP.go
									
									
									
									
									
								
							
							
						
						
									
										14
									
								
								xP/xP.go
									
									
									
									
									
								
							| @ -22,6 +22,7 @@ import ( | |||||||
| var ( | var ( | ||||||
| 	addressBind    string | 	addressBind    string | ||||||
| 	addressConnect string | 	addressConnect string | ||||||
|  | 	addressWS      string | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| func clientToRelay( | func clientToRelay( | ||||||
| @ -144,6 +145,7 @@ var page = template.Must(template.New("/").Parse(`<!DOCTYPE html> | |||||||
| <head> | <head> | ||||||
| 	<title>xP</title> | 	<title>xP</title> | ||||||
| 	<meta charset="utf-8" /> | 	<meta charset="utf-8" /> | ||||||
|  | 	<meta name="viewport" content="width=device-width, initial-scale=1"> | ||||||
| 	<link rel="stylesheet" href="xP.css" /> | 	<link rel="stylesheet" href="xP.css" /> | ||||||
| </head> | </head> | ||||||
| <body> | <body> | ||||||
| @ -163,18 +165,24 @@ func handleDefault(w http.ResponseWriter, r *http.Request) { | |||||||
| 		return | 		return | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	wsURI := fmt.Sprintf("ws://%s/ws", r.Host) | 	wsURI := addressWS | ||||||
|  | 	if wsURI == "" { | ||||||
|  | 		wsURI = fmt.Sprintf("ws://%s/ws", r.Host) | ||||||
|  | 	} | ||||||
| 	if err := page.Execute(w, wsURI); err != nil { | 	if err := page.Execute(w, wsURI); err != nil { | ||||||
| 		log.Println("Template execution failed: " + err.Error()) | 		log.Println("Template execution failed: " + err.Error()) | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func main() { | func main() { | ||||||
| 	if len(os.Args) != 3 { | 	if len(os.Args) < 3 || len(os.Args) > 4 { | ||||||
| 		log.Fatalf("usage: %s BIND CONNECT\n", os.Args[0]) | 		log.Fatalf("usage: %s BIND CONNECT [WSURI]\n", os.Args[0]) | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	addressBind, addressConnect = os.Args[1], os.Args[2] | 	addressBind, addressConnect = os.Args[1], os.Args[2] | ||||||
|  | 	if len(os.Args) > 3 { | ||||||
|  | 		addressWS = os.Args[3] | ||||||
|  | 	} | ||||||
| 
 | 
 | ||||||
| 	http.Handle("/ws", websocket.Handler(handleWebSocket)) | 	http.Handle("/ws", websocket.Handler(handleWebSocket)) | ||||||
| 	http.Handle("/", http.HandlerFunc(handleDefault)) | 	http.Handle("/", http.HandlerFunc(handleDefault)) | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user