Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
C
caddy
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
nexedi
caddy
Commits
37f0a37e
Commit
37f0a37e
authored
Mar 03, 2015
by
Matthew Holt
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Filled out more web socket stuff
parent
411f3256
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
94 additions
and
21 deletions
+94
-21
middleware/websockets/websocket.go
middleware/websockets/websocket.go
+66
-8
middleware/websockets/websockets.go
middleware/websockets/websockets.go
+28
-13
No files found.
middleware/websockets/websocket.go
View file @
37f0a37e
package
websockets
package
websockets
import
(
import
(
"net"
"net/http"
"os/exec"
"os/exec"
"strings"
"golang.org/x/net/websocket"
"golang.org/x/net/websocket"
)
)
// WebSocket represents a web socket server configuration.
// WebSocket represents a web socket server instance. A WebSocket
// struct is instantiated for each new websocket request.
type
WebSocket
struct
{
type
WebSocket
struct
{
Path
string
WSConfig
Command
string
*
http
.
Request
Arguments
[]
string
}
}
// Handle handles a WebSocket connection. It launches the
// Handle handles a WebSocket connection. It launches the
...
@@ -21,12 +24,67 @@ func (ws WebSocket) Handle(conn *websocket.Conn) {
...
@@ -21,12 +24,67 @@ func (ws WebSocket) Handle(conn *websocket.Conn) {
cmd
.
Stdin
=
conn
cmd
.
Stdin
=
conn
cmd
.
Stdout
=
conn
cmd
.
Stdout
=
conn
// TODO: Set environment variables according to CGI 1.1
err
:=
ws
.
buildEnv
(
cmd
)
// cf. http://tools.ietf.org/html/rfc3875#section-4.1.4
if
err
!=
nil
{
cmd
.
Env
=
append
(
cmd
.
Env
,
`GATEWAY_INTERFACE="caddy-CGI/1.1"`
)
// TODO
}
err
:
=
cmd
.
Run
()
err
=
cmd
.
Run
()
if
err
!=
nil
{
if
err
!=
nil
{
panic
(
err
)
panic
(
err
)
}
}
}
}
// buildEnv sets the meta-variables for the child process according
// to the CGI 1.1 specification: http://tools.ietf.org/html/rfc3875#section-4.1
func
(
ws
WebSocket
)
buildEnv
(
cmd
*
exec
.
Cmd
)
error
{
remoteHost
,
remotePort
,
err
:=
net
.
SplitHostPort
(
ws
.
RemoteAddr
)
if
err
!=
nil
{
return
err
}
serverHost
,
serverPort
,
err
:=
net
.
SplitHostPort
(
ws
.
Host
)
if
err
!=
nil
{
return
err
}
cmd
.
Env
=
[]
string
{
`AUTH_TYPE=`
,
// Not used
`CONTENT_LENGTH=`
,
// Not used
`CONTENT_TYPE=`
,
// Not used
`GATEWAY_INTERFACE=`
+
gatewayInterface
,
`PATH_INFO=`
,
// TODO
`PATH_TRANSLATED=`
,
// TODO
`QUERY_STRING=`
+
ws
.
URL
.
RawQuery
,
`REMOTE_ADDR=`
+
remoteHost
,
`REMOTE_HOST=`
+
remoteHost
,
// TODO (Host lookups are slow; make this configurable)
`REMOTE_IDENT=`
,
// Not used
`REMOTE_PORT=`
+
remotePort
,
`REMOTE_USER=`
,
// Not used,
`REQUEST_METHOD=`
+
ws
.
Method
,
`REQUEST_URI=`
+
ws
.
RequestURI
,
`SCRIPT_NAME=`
,
// TODO - absolute path to program being executed?
`SERVER_NAME=`
+
serverHost
,
`SERVER_PORT=`
+
serverPort
,
`SERVER_PROTOCOL=`
+
ws
.
Proto
,
`SERVER_SOFTWARE=`
+
serverSoftware
,
}
// Add each HTTP header to the environment as well
for
header
,
values
:=
range
ws
.
Header
{
value
:=
strings
.
Join
(
values
,
", "
)
header
=
strings
.
ToUpper
(
header
)
header
=
strings
.
Replace
(
header
,
"-"
,
"_"
,
-
1
)
value
=
strings
.
Replace
(
value
,
"
\n
"
,
" "
,
-
1
)
cmd
.
Env
=
append
(
cmd
.
Env
,
"HTTP_"
+
header
+
"="
+
value
)
}
return
nil
}
const
(
// See CGI spec, 4.1.4
gatewayInterface
=
"caddy-CGI/1.1"
// See CGI spec, 4.1.17
serverSoftware
=
"caddy/0.1.0"
)
middleware/websockets/websockets.go
View file @
37f0a37e
...
@@ -4,7 +4,7 @@
...
@@ -4,7 +4,7 @@
package
websockets
package
websockets
import
(
import
(
"
log
"
"
errors
"
"net/http"
"net/http"
"github.com/flynn/go-shlex"
"github.com/flynn/go-shlex"
...
@@ -12,16 +12,31 @@ import (
...
@@ -12,16 +12,31 @@ import (
"golang.org/x/net/websocket"
"golang.org/x/net/websocket"
)
)
// WebSockets is a type which holds configuration
type
(
// for the websocket middleware collectively.
// WebSockets is a type that holds configuration for the
type
WebSockets
struct
{
// websocket middleware generally, like a list of all the
Sockets
[]
WebSocket
// websocket endpoints.
}
WebSockets
struct
{
Sockets
[]
WSConfig
}
// WSConfig holds the configuration for a single websocket
// endpoint which may serve zero or more websocket connections.
WSConfig
struct
{
Path
string
Command
string
Arguments
[]
string
}
)
// ServeHTTP
more or less converts the HTTP request to a WebSocket connection
.
// ServeHTTP
converts the HTTP request to a WebSocket connection and serves it up
.
func
(
ws
WebSockets
)
ServeHTTP
(
w
http
.
ResponseWriter
,
r
*
http
.
Request
)
{
func
(
ws
WebSockets
)
ServeHTTP
(
w
http
.
ResponseWriter
,
r
*
http
.
Request
)
{
for
_
,
socket
:=
range
ws
.
Sockets
{
for
_
,
sockconfig
:=
range
ws
.
Sockets
{
if
middleware
.
Path
(
r
.
URL
.
Path
)
.
Matches
(
socket
.
Path
)
{
if
middleware
.
Path
(
r
.
URL
.
Path
)
.
Matches
(
sockconfig
.
Path
)
{
socket
:=
WebSocket
{
WSConfig
:
sockconfig
,
Request
:
r
,
}
websocket
.
Handler
(
socket
.
Handle
)
.
ServeHTTP
(
w
,
r
)
websocket
.
Handler
(
socket
.
Handle
)
.
ServeHTTP
(
w
,
r
)
return
return
}
}
...
@@ -30,7 +45,7 @@ func (ws WebSockets) ServeHTTP(w http.ResponseWriter, r *http.Request) {
...
@@ -30,7 +45,7 @@ func (ws WebSockets) ServeHTTP(w http.ResponseWriter, r *http.Request) {
// New constructs and configures a new websockets middleware instance.
// New constructs and configures a new websockets middleware instance.
func
New
(
c
middleware
.
Controller
)
(
middleware
.
Middleware
,
error
)
{
func
New
(
c
middleware
.
Controller
)
(
middleware
.
Middleware
,
error
)
{
var
websocks
[]
W
ebSocket
var
websocks
[]
W
SConfig
var
path
string
var
path
string
var
command
string
var
command
string
...
@@ -62,9 +77,9 @@ func New(c middleware.Controller) (middleware.Middleware, error) {
...
@@ -62,9 +77,9 @@ func New(c middleware.Controller) (middleware.Middleware, error) {
parts
,
err
:=
shlex
.
Split
(
command
)
parts
,
err
:=
shlex
.
Split
(
command
)
if
err
!=
nil
{
if
err
!=
nil
{
log
.
Fatal
(
"Error parsing command for websocket use: "
+
err
.
Error
())
return
nil
,
errors
.
New
(
"Error parsing command for websocket use: "
+
err
.
Error
())
}
else
if
len
(
parts
)
==
0
{
}
else
if
len
(
parts
)
==
0
{
log
.
Fatal
(
"No command found for use by websocket.
"
)
return
nil
,
errors
.
New
(
"No command found for use by websocket
"
)
}
}
cmd
=
parts
[
0
]
cmd
=
parts
[
0
]
...
@@ -72,7 +87,7 @@ func New(c middleware.Controller) (middleware.Middleware, error) {
...
@@ -72,7 +87,7 @@ func New(c middleware.Controller) (middleware.Middleware, error) {
args
=
parts
[
1
:
]
args
=
parts
[
1
:
]
}
}
websocks
=
append
(
websocks
,
W
ebSocket
{
websocks
=
append
(
websocks
,
W
SConfig
{
Path
:
path
,
Path
:
path
,
Command
:
cmd
,
Command
:
cmd
,
Arguments
:
args
,
Arguments
:
args
,
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment