Skip to content

Commit

Permalink
Merge pull request #78 from fakefloordiv/master
Browse files Browse the repository at this point in the history
v0.5.0: Added new features, improved old ones
  • Loading branch information
flrdv authored Mar 9, 2023
2 parents fac142b + 186637b commit 45e5742
Show file tree
Hide file tree
Showing 33 changed files with 523 additions and 282 deletions.
7 changes: 5 additions & 2 deletions examples/combined/combined.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,16 @@ var (
)

func Index(request *http.Request) http.Response {
return http.RespondTo(request).WithFile(index, func(err error) http.Response {
resp, err := http.RespondTo(request).WithFile(index)
if err != nil {
return http.RespondTo(request).
WithCode(status.NotFound).
WithBody(
index + ": not found; try running this example directly from examples/combined folder",
)
})
}

return resp
}

func IndexSay(request *http.Request) http.Response {
Expand Down
21 changes: 10 additions & 11 deletions http/query/query.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,21 +9,20 @@ import (
var ErrNoSuchKey = errors.New("desired key does not exists")

type (
rawQuery []byte
parsedQuery map[string][]byte

queryFactory func() map[string][]byte
rawQuery []byte
Map = map[string]string
mapFactory func() Map
)

// Query is optional, it may contain rawQuery, but it will not be parsed until
// needed
type Query struct {
rawQuery rawQuery
parsedQuery parsedQuery
queryFactory queryFactory
parsedQuery Map
queryFactory mapFactory
}

func NewQuery(queryFactory queryFactory) Query {
func NewQuery(queryFactory mapFactory) Query {
return Query{
queryFactory: queryFactory,
}
Expand All @@ -37,16 +36,16 @@ func (q *Query) Set(raw []byte) {
q.parsedQuery = nil
}

// Get is responsible for getting a key from query query. In case this
// Get is responsible for getting a key from query. In case this
// method is called a first time since rawQuery was set (or not set
// at all), rawQuery bytearray will be parsed and value returned
// (or ErrNoSuchKey instead). In case of invalid query bytearray,
// ErrBadQuery will be returned
func (q *Query) Get(key string) (value []byte, err error) {
func (q *Query) Get(key string) (value string, err error) {
if q.parsedQuery == nil {
q.parsedQuery, err = queryparser.Parse(q.rawQuery, q.queryFactory)
if err != nil {
return nil, err
return "", err
}
}

Expand All @@ -59,6 +58,6 @@ func (q *Query) Get(key string) (value []byte, err error) {
}

// Raw just returns a raw value of query as it is
func (q Query) Raw() []byte {
func (q *Query) Raw() []byte {
return q.rawQuery
}
6 changes: 3 additions & 3 deletions http/query/query_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@ func TestQuery(t *testing.T) {
// here we test laziness of query

// just test that passed buffer's content will not be used
query := NewQuery(func() map[string][]byte {
return make(map[string][]byte)
query := NewQuery(func() Map {
return make(Map)
})
query.Set([]byte("hello=world"))
require.Equal(t, "hello=world", string(query.rawQuery))
Expand All @@ -20,7 +20,7 @@ func TestQuery(t *testing.T) {
t.Run("GetExistingKey", func(t *testing.T) {
value, err := query.Get("hello")
require.NoError(t, err)
require.Equal(t, "world", string(value))
require.Equal(t, "world", value)
})

t.Run("GetNonExistingKey", func(t *testing.T) {
Expand Down
64 changes: 39 additions & 25 deletions http/request.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,20 +23,26 @@ type (
)

type (
Path = string
Params = map[string]string

Path struct {
String string
Params Params
Query query.Query
Fragment Fragment
}

Fragment = string
)

// Request struct represents http request
// About headers manager see at http/headers/headers.go:Manager
// Headers attribute references at that one that lays in manager
type Request struct {
Method method.Method
Path Path
Query query.Query
Fragment Fragment
Proto proto.Proto
Remote net.Addr
Method method.Method
Path Path
Proto proto.Proto
Remote net.Addr

Headers headers.Headers

Expand All @@ -47,33 +53,35 @@ type Request struct {
body BodyReader
bodyBuff []byte

Ctx context.Context
response Response
conn net.Conn
wasHijacked bool
Ctx context.Context
response Response
conn net.Conn
wasHijacked bool
clearParamsMap bool
}

// NewRequest returns a new instance of request object and body gateway
// Must not be used externally, this function is for internal purposes only
// HTTP/1.1 as a protocol by default is set because if first request from user
// is invalid, we need to render a response using request method, but appears
// that default method is a null-value (proto.Unknown)
// Also query.Query is being constructed right here instead of passing from outside
// because it has only optional purposes and buff will be nil anyway
// But maybe it's better to implement DI all the way we go? I don't know, maybe
// someone will contribute and fix this
func NewRequest(
hdrs headers.Headers, query query.Query, response Response, conn net.Conn, body BodyReader,
paramsMap Params, disableParamsMapClearing bool,
) *Request {
request := &Request{
Query: query,
Proto: proto.HTTP11,
Headers: hdrs,
Remote: conn.RemoteAddr(),
conn: conn,
body: body,
Ctx: context.Background(),
response: response,
Path: Path{
Params: paramsMap,
Query: query,
},
Proto: proto.HTTP11,
Headers: hdrs,
Remote: conn.RemoteAddr(),
conn: conn,
body: body,
Ctx: context.Background(),
response: response,
clearParamsMap: !disableParamsMapClearing,
}

return request
Expand Down Expand Up @@ -160,8 +168,8 @@ func (r *Request) WasHijacked() bool {
// Clear resets request headers and reads body into nowhere until completed.
// It is implemented to clear the request object between requests
func (r *Request) Clear() (err error) {
r.Fragment = ""
r.Query.Set(nil)
r.Path.Fragment = ""
r.Path.Query.Set(nil)
r.Ctx = context.Background()
r.response = r.response.Clear()

Expand All @@ -173,6 +181,12 @@ func (r *Request) Clear() (err error) {
r.IsChunked = false
r.Upgrade = proto.Unknown

if r.clearParamsMap && len(r.Path.Params) > 0 {
for k := range r.Path.Params {
delete(r.Path.Params, k)
}
}

return nil
}

Expand Down
Loading

0 comments on commit 45e5742

Please sign in to comment.