hockeypuck team mailing list archive
-
hockeypuck team
-
Mailing list archive
-
Message #00077
[Merge] ~alejdg/hockeypuck:124887 into hockeypuck:master
Alexandre Gomes has proposed merging ~alejdg/hockeypuck:124887 into hockeypuck:master.
Requested reviews:
Hockeypuck (hockeypuck)
For more details, see:
https://code.launchpad.net/~alejdg/hockeypuck/+git/hockeypuck/+merge/413895
--
Your team Hockeypuck is requested to review the proposed merge of ~alejdg/hockeypuck:124887 into hockeypuck:master.
diff --git a/src/hockeypuck/hkp/handler.go b/src/hockeypuck/hkp/handler.go
index 00ce4b3..3adecf6 100644
--- a/src/hockeypuck/hkp/handler.go
+++ b/src/hockeypuck/hkp/handler.go
@@ -45,6 +45,7 @@ const (
shortKeyIDLen = 8
longKeyIDLen = 16
fingerprintKeyIDLen = 40
+ maxRespLen = 116997644
)
var errKeywordSearchNotAvailable = errors.New("keyword search is not available")
@@ -70,6 +71,7 @@ type Handler struct {
keyReaderOptions []openpgp.KeyReaderOption
keyWriterOptions []openpgp.KeyWriterOption
+ maxRespLen int
}
type HandlerOption func(h *Handler) error
@@ -160,7 +162,8 @@ func KeyWriterOptions(opts []openpgp.KeyWriterOption) HandlerOption {
func NewHandler(storage storage.Storage, options ...HandlerOption) (*Handler, error) {
h := &Handler{
- storage: storage,
+ storage: storage,
+ maxRespLen: maxRespLen,
}
for _, option := range options {
err := option(h)
@@ -171,6 +174,15 @@ func NewHandler(storage storage.Storage, options ...HandlerOption) (*Handler, er
return h, nil
}
+func NewHandlerWithLen(storage storage.Storage, maxRespLen int, options ...HandlerOption) (*Handler, error) {
+ h, err := NewHandler(storage, options...)
+ if err != nil {
+ return nil, errors.WithStack(err)
+ }
+ h.maxRespLen = maxRespLen
+ return h, nil
+}
+
func (h *Handler) Register(r *httprouter.Router) {
r.GET("/pks/lookup", h.Lookup)
r.POST("/pks/add", h.Add)
@@ -207,6 +219,7 @@ func (h *Handler) HashQuery(w http.ResponseWriter, r *http.Request, _ httprouter
return
}
var result []*openpgp.PrimaryKey
+ rl := 0
for _, digest := range hq.Digests {
rfps, err := h.storage.MatchMD5([]string{digest})
if err != nil {
@@ -219,12 +232,17 @@ func (h *Handler) HashQuery(w http.ResponseWriter, r *http.Request, _ httprouter
continue
}
result = append(result, keys...)
+ rl = rl + keys[0].Length
+ if rl >= h.maxRespLen {
+ log.Infof("Response too lengthy, limiting it to %dKB", h.maxRespLen)
+ break
+ }
}
w.Header().Set("Content-Type", "pgp/keys")
// Write the number of keys
- err = recon.WriteInt(w, len(result))
+ _ = recon.WriteInt(w, len(result))
for _, key := range result {
// Write each key in binary packet format, prefixed with length
err = writeHashqueryKey(w, key)
@@ -571,7 +589,6 @@ func (h *Handler) Delete(w http.ResponseWriter, r *http.Request, _ httprouter.Pa
"deleted": []string{signingFp},
}).Info("delete")
- return
}
func (h *Handler) checkSignature(keytext, keysig string) (string, error) {
diff --git a/src/hockeypuck/hkp/handler_test.go b/src/hockeypuck/hkp/handler_test.go
index 85ca3b6..6121995 100644
--- a/src/hockeypuck/hkp/handler_test.go
+++ b/src/hockeypuck/hkp/handler_test.go
@@ -19,6 +19,7 @@ package hkp
import (
"bytes"
+ "crypto/md5"
"encoding/json"
"fmt"
"io/ioutil"
@@ -30,6 +31,7 @@ import (
"github.com/julienschmidt/httprouter"
gc "gopkg.in/check.v1"
+ "hockeypuck/conflux/recon"
"hockeypuck/openpgp"
"hockeypuck/testing"
@@ -72,6 +74,8 @@ func Test(t *stdtesting.T) { gc.TestingT(t) }
type HandlerSuite struct {
storage *mock.Storage
srv *httptest.Server
+ handler *Handler
+ digests int
}
var _ = gc.Suite(&HandlerSuite{})
@@ -97,8 +101,10 @@ func (s *HandlerSuite) SetUpTest(c *gc.C) {
r := httprouter.New()
handler, err := NewHandler(s.storage)
c.Assert(err, gc.IsNil)
- handler.Register(r)
+ s.handler = handler
+ s.handler.Register(r)
s.srv = httptest.NewServer(r)
+ s.digests = 50
}
func (s *HandlerSuite) TearDownTest(c *gc.C) {
@@ -246,3 +252,55 @@ func (s *HandlerSuite) TestFetchWithBadSigs(c *gc.C) {
c.Assert(keys[0].ShortID(), gc.Equals, tk.sid)
c.Assert(len(keys[0].Others), gc.Equals, 0)
}
+
+func (s *HandlerSuite) SetupHashQueryTest(c *gc.C) (*httptest.ResponseRecorder, *http.Request) {
+ // Determine reference digest to compare with
+ h := md5.New()
+ refDigest := h.Sum(nil)
+ url, err := url.Parse("/pks/hashquery")
+ c.Assert(err, gc.IsNil)
+ var buf bytes.Buffer
+ c.Assert(err, gc.IsNil)
+ err = recon.WriteInt(&buf, s.digests)
+ c.Assert(err, gc.IsNil)
+ for i := 0; i < s.digests; i++ {
+ err = recon.WriteInt(&buf, len(refDigest))
+ c.Assert(err, gc.IsNil)
+ _, err = buf.Write(refDigest)
+ c.Assert(err, gc.IsNil)
+ }
+ // Create an HTTP request
+ req := &http.Request{
+ Method: "POST",
+ URL: url,
+ Body: ioutil.NopCloser(bytes.NewBuffer(buf.Bytes())),
+ }
+ w := httptest.NewRecorder()
+
+ return w, req
+}
+
+func (s *HandlerSuite) TestHashQuery(c *gc.C) {
+ w, req := s.SetupHashQueryTest(c)
+ s.handler.HashQuery(w, req, nil)
+ // Number of keys in response based on the length estimation of one key
+ nk := w.Body.Len() / 1446
+ // The number of keys should be the same as the number of digests
+ c.Assert(nk, gc.Equals, s.digests)
+}
+
+func (s *HandlerSuite) TestHashQueryResponseTooLong(c *gc.C) {
+ var err error
+ w, req := s.SetupHashQueryTest(c)
+
+ // Test HashQuery when the response is too long
+ // Reduce the response max length for testing purposes
+ s.handler, err = NewHandlerWithLen(s.storage, 14460)
+ c.Assert(err, gc.IsNil)
+ s.handler.HashQuery(w, req, nil)
+ // Number of keys in response based on the length estimation of one key
+ nk := w.Body.Len() / 1446
+ // The number of keys cannot be the same as the number of digests as the response
+ // is being limited
+ c.Assert(nk, gc.Not(gc.Equals), s.digests)
+}
Follow ups