ws/internal/http/upgrade/request/parser/reqline/private.go

73 lines
1.6 KiB
Go

package reqline
import (
"regexp"
"fmt"
)
// extractHttpMethod extracts the HTTP method from a []byte
// and checks for errors
// allowed format: OPTIONS|GET|HEAD|POST|PUT|DELETE
func (r *T) extractHttpMethod(b []byte) error {
switch string(b) {
case "OPTIONS": r.method = OPTIONS
case "GET": r.method = GET
case "HEAD": r.method = HEAD
case "POST": r.method = POST
case "PUT": r.method = PUT
case "DELETE": r.method = DELETE
default:
return fmt.Errorf("Unknown HTTP method '%s'", b)
}
return nil
}
// extractURI extracts the URI from a []byte and checks for errors
// allowed format: /([^/]/)*/?
func (r *T) extractURI(b []byte) error {
/* (1) Check format */
checker := regexp.MustCompile("^(?:/[^/]+)*/?$")
if !checker.Match(b) {
return fmt.Errorf("Invalid URI format, expected an absolute path (starts with /), got '%s'", b)
}
/* (2) Store */
r.uri = string(b)
return nil
}
// extractHttpVersion extracts the version and checks for errors
// allowed format: [1-9] or [1.9].[0-9]
func (r *T) extractHttpVersion(b []byte) error {
/* (1) Extract version parts */
extractor := regexp.MustCompile(`^HTTP/([1-9])(?:\.([0-9]))?$`);
if !extractor.Match(b) {
return fmt.Errorf("Cannot parse HTTP version, expected INT or INT.INT, got '%s'", b)
}
/* (2) Extract version number */
matches := extractor.FindSubmatch(b)
var version byte = matches[1][0] - '0'
/* (3) Extract subversion (if exists) */
var subVersion byte = 0
if len(matches[2]) > 0 {
subVersion = matches[2][0] - '0'
}
/* (4) Store version (x 10 to fit uint8) */
r.version = version * 10 + subVersion
return nil
}