added request status code (defined in response) for creation from request to response
This commit is contained in:
parent
08b73e87ad
commit
d743448fce
|
@ -45,6 +45,7 @@ func manageClient(sock net.Conn) {
|
|||
|
||||
req, err := request.Build(sock)
|
||||
if err != nil {
|
||||
fmt.Printf("STATUS CODE: %d %s\n", req.StatusCode(), req.StatusCode().Explicit())
|
||||
panic(err)
|
||||
}
|
||||
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package request
|
||||
|
||||
import (
|
||||
"git.xdrm.io/gws/http/upgrade/response"
|
||||
"git.xdrm.io/gws/internal/http/upgrade/request/parser/header"
|
||||
"fmt"
|
||||
"strconv"
|
||||
|
@ -28,6 +29,7 @@ func (r *T) extractHostPort(bb header.HeaderValue) error {
|
|||
// extract port
|
||||
readPort, err := strconv.ParseUint(split[1], 10, 16)
|
||||
if err != nil {
|
||||
r.code = response.BAD_REQUEST
|
||||
return fmt.Errorf("Cannot read port number '%s'", split[1])
|
||||
}
|
||||
|
||||
|
@ -35,8 +37,9 @@ func (r *T) extractHostPort(bb header.HeaderValue) error {
|
|||
|
||||
// if 'Origin' header is already read, check it
|
||||
if len(r.origin) > 0 {
|
||||
err = r.checkOriginPolicy()
|
||||
if err != nil {
|
||||
err = r.checkOriginPolicy()
|
||||
r.code = response.FORBIDDEN
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
@ -50,6 +53,7 @@ func (r *T) extractHostPort(bb header.HeaderValue) error {
|
|||
func (r *T) extractOrigin(bb header.HeaderValue) error {
|
||||
|
||||
if len(bb) != 1 {
|
||||
r.code = response.FORBIDDEN
|
||||
return fmt.Errorf("Origin header must have a unique value")
|
||||
}
|
||||
|
||||
|
@ -59,6 +63,7 @@ func (r *T) extractOrigin(bb header.HeaderValue) error {
|
|||
if len(r.host) > 0 {
|
||||
err := r.checkOriginPolicy()
|
||||
if err != nil {
|
||||
r.code = response.FORBIDDEN
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
@ -87,6 +92,7 @@ func (r *T) checkConnection(bb header.HeaderValue) error {
|
|||
|
||||
}
|
||||
|
||||
r.code = response.BAD_REQUEST
|
||||
return fmt.Errorf("Connection header must be 'Upgrade'")
|
||||
|
||||
}
|
||||
|
@ -96,6 +102,7 @@ func (r *T) checkConnection(bb header.HeaderValue) error {
|
|||
func (r *T) checkUpgrade(bb header.HeaderValue) error {
|
||||
|
||||
if len(bb) != 1 {
|
||||
r.code = response.BAD_REQUEST
|
||||
return fmt.Errorf("Upgrade header must have only 1 element")
|
||||
}
|
||||
|
||||
|
@ -104,6 +111,7 @@ func (r *T) checkUpgrade(bb header.HeaderValue) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
r.code = response.BAD_REQUEST
|
||||
return fmt.Errorf("Upgrade header must be 'websocket', got '%s'", bb[0])
|
||||
|
||||
}
|
||||
|
@ -113,6 +121,7 @@ func (r *T) checkUpgrade(bb header.HeaderValue) error {
|
|||
func (r *T) checkVersion(bb header.HeaderValue) error {
|
||||
|
||||
if len(bb) != 1 || string(bb[0]) != "13" {
|
||||
r.code = response.UPGRADE_REQUIRED
|
||||
return fmt.Errorf("Sec-WebSocket-Version header must be '13'")
|
||||
}
|
||||
|
||||
|
@ -126,6 +135,7 @@ func (r *T) checkVersion(bb header.HeaderValue) error {
|
|||
func (r *T) extractKey(bb header.HeaderValue) error {
|
||||
|
||||
if len(bb) != 1 || len(bb[0]) != 24 {
|
||||
r.code = response.BAD_REQUEST
|
||||
return fmt.Errorf("Sec-WebSocket-Key header must be a unique 24 bytes base64 value, got %d bytes", len(bb[0]))
|
||||
}
|
||||
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package request
|
||||
|
||||
import (
|
||||
"git.xdrm.io/gws/http/upgrade/response"
|
||||
"fmt"
|
||||
"git.xdrm.io/gws/internal/http/upgrade/request/parser/header"
|
||||
)
|
||||
|
@ -17,6 +18,7 @@ func (r *T) parseHeader(b []byte) error {
|
|||
err := r.request.Parse(b)
|
||||
|
||||
if err != nil {
|
||||
r.code = response.BAD_REQUEST
|
||||
return fmt.Errorf("Error while parsing first line: %s", err)
|
||||
}
|
||||
|
||||
|
@ -32,6 +34,7 @@ func (r *T) parseHeader(b []byte) error {
|
|||
/* (1) Try to parse header */
|
||||
head, err := header.Parse(b)
|
||||
if err != nil {
|
||||
r.code = response.BAD_REQUEST
|
||||
return fmt.Errorf("Error parsing header: %s", err)
|
||||
}
|
||||
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package request
|
||||
|
||||
import (
|
||||
"git.xdrm.io/gws/http/upgrade/response"
|
||||
"git.xdrm.io/gws/internal/http/reader"
|
||||
"fmt"
|
||||
"io"
|
||||
|
@ -10,18 +11,19 @@ import (
|
|||
// from a reader (typically bufio.NewRead of the socket)
|
||||
func Build(r io.Reader) (request *T, err error) {
|
||||
|
||||
req := new(T)
|
||||
req.code = 500
|
||||
|
||||
|
||||
/* (1) Parse request
|
||||
---------------------------------------------------------*/
|
||||
/* (1) Get chunk reader */
|
||||
cr := reader.NewReader(r)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("Error while creating chunk reader: %s", err)
|
||||
return req, fmt.Errorf("Error while creating chunk reader: %s", err)
|
||||
}
|
||||
|
||||
/* (2) Init request */
|
||||
req := new(T)
|
||||
|
||||
/* (3) Parse header line by line */
|
||||
/* (2) Parse header line by line */
|
||||
for {
|
||||
|
||||
line, err := cr.Read()
|
||||
|
@ -30,21 +32,22 @@ func Build(r io.Reader) (request *T, err error) {
|
|||
}
|
||||
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("Cannot read from reader: %s", err)
|
||||
return req, fmt.Errorf("Cannot read from reader: %s", err)
|
||||
}
|
||||
|
||||
err = req.parseHeader(line)
|
||||
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("Parsing error: %s\n", err);
|
||||
return req, fmt.Errorf("Parsing error: %s\n", err);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* (4) Check completion */
|
||||
/* (3) Check completion */
|
||||
err = req.isComplete()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
req.code = response.BAD_REQUEST
|
||||
return req, err
|
||||
}
|
||||
|
||||
|
||||
|
@ -60,7 +63,14 @@ func (r T) String() string{
|
|||
l1 := fmt.Sprintf("Upgrade Request\n - host: %s\n - port: %d\n - origin: %s\n", r.host, r.port, r.origin)
|
||||
l2 := fmt.Sprintf(" - origin policy: %t\n - connection header: %t\n - upgrade header: %t\n - valid ws version: %t\n", r.validPolicy, r.hasConnection, r.hasUpgrade, r.hasVersion)
|
||||
l3 := fmt.Sprintf(" - key: %s\n - protocols: %s\n", r.key, r.protocols)
|
||||
l4 := fmt.Sprintf(" - current status: %d %s\n", r.code, r.code.Explicit())
|
||||
|
||||
|
||||
return fmt.Sprintf("%s%s%s", l1, l2, l3)
|
||||
}
|
||||
return fmt.Sprintf("%s%s%s%s", l1, l2, l3, l4)
|
||||
}
|
||||
|
||||
|
||||
// StatusCode returns the status current
|
||||
func (r T) StatusCode() response.StatusCode {
|
||||
return r.code
|
||||
}
|
||||
|
|
|
@ -1,11 +1,15 @@
|
|||
package request
|
||||
|
||||
import "git.xdrm.io/gws/internal/http/upgrade/request/parser/reqline"
|
||||
import "git.xdrm.io/gws/http/upgrade/response"
|
||||
|
||||
// T represents an HTTP Upgrade request
|
||||
type T struct {
|
||||
first bool // whether the first line has been read (GET uri HTTP/version)
|
||||
|
||||
// status code
|
||||
code response.StatusCode
|
||||
|
||||
// request line
|
||||
request reqline.T
|
||||
|
||||
|
|
|
@ -0,0 +1,25 @@
|
|||
package response
|
||||
|
||||
// StatusCode maps the status codes (and description)
|
||||
type StatusCode uint16
|
||||
|
||||
var SWITCHING_PROTOCOLS StatusCode = 101 // handshake success
|
||||
var BAD_REQUEST StatusCode = 400 // missing/malformed headers
|
||||
var FORBIDDEN StatusCode = 403 // invalid origin policy, TLS required
|
||||
var UPGRADE_REQUIRED StatusCode = 426 // invalid WS version
|
||||
var NOT_FOUND StatusCode = 404 // unserved or invalid URI
|
||||
var INTERNAL StatusCode = 500 // custom error
|
||||
|
||||
func (sc StatusCode) Explicit() string {
|
||||
|
||||
switch sc {
|
||||
case SWITCHING_PROTOCOLS: return "Switching Protocols"
|
||||
case BAD_REQUEST: return "Bad Request"
|
||||
case FORBIDDEN: return "Forbidden"
|
||||
case UPGRADE_REQUIRED: return "Upgrade Required"
|
||||
case NOT_FOUND: return "Not Found"
|
||||
case INTERNAL: return "Internal Server Error"
|
||||
default:
|
||||
return "Unknown Status Code"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,9 @@
|
|||
package response
|
||||
|
||||
// T represents an HTTP Upgrade Response
|
||||
type T struct {
|
||||
|
||||
code StatusCode // status code
|
||||
accept []byte // processed from Sec-WebSocket-Key
|
||||
protocol []byte // set from Sec-WebSocket-Protocol or none if not received
|
||||
}
|
Loading…
Reference in New Issue