Skip to content

Commit

Permalink
Merge pull request #75 from lbryio/feature/unified_endpoint
Browse files Browse the repository at this point in the history
Feature/unified endpoint
  • Loading branch information
anbsky committed Sep 17, 2019
2 parents dba4889 + 70b9921 commit fbdc892
Show file tree
Hide file tree
Showing 9 changed files with 200 additions and 109 deletions.
2 changes: 1 addition & 1 deletion api/handlers_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import (
"github.com/stretchr/testify/assert"
)

func TestContentByURL_NoPayment(t *testing.T) {
func TestContentByURLNoPayment(t *testing.T) {
r, _ := http.NewRequest("GET", "http://localhost:40080/content/url", nil)
r.URL.RawQuery = "pra-onde-vamos-em-2018-seguran-a-online#3a508cce1fda3b7c1a2502cb4323141d40a2cf0b"
r.Header.Add("Range", "bytes=0-1023")
Expand Down
23 changes: 13 additions & 10 deletions api/routes.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,25 +4,28 @@ import (
"github.com/lbryio/lbrytv/app/proxy"
"github.com/lbryio/lbrytv/app/publish"
"github.com/lbryio/lbrytv/app/users"
"github.com/lbryio/lbrytv/config"

"github.com/gorilla/mux"
)

// InstallRoutes sets up global API handlers
func InstallRoutes(proxyService *proxy.Service, r *mux.Router) {
r.HandleFunc("/", Index)
authenticator := users.NewAuthenticator(users.NewUserService())
proxyHandler := proxy.NewRequestHandler(proxyService)
upHandler, err := publish.NewUploadHandler(publish.UploadOpts{ProxyService: proxyService})
if err != nil {
panic(err)
}

proxyHandler := proxy.NewRequestServer(proxyService)
r.HandleFunc("/", Index)
v1Router := r.PathPrefix("/api/v1").Subrouter()
v1Router.HandleFunc("/proxy", authenticator.Wrap(upHandler.Handle)).MatcherFunc(upHandler.CanHandle)
v1Router.HandleFunc("/proxy", captureErrors(proxyHandler.Handle))

// TODO: For temporary backwards compatibility, remove after JS code has been updated to use paths above
r.HandleFunc("/api/proxy", captureErrors(proxyHandler.Handle))
r.HandleFunc("/api/proxy/", captureErrors(proxyHandler.Handle))
r.HandleFunc("/content/claims/{uri}/{claim}/{filename}", captureErrors(ContentByClaimsURI))
r.HandleFunc("/content/url", captureErrors(ContentByURL))

actionsRouter := r.PathPrefix("/api/v1/actions").Subrouter()
authenticator := users.NewAuthenticator(users.NewUserService())
lbrynetPublisher := &publish.LbrynetPublisher{Service: proxyService}
UploadHandler := publish.NewUploadHandler(config.GetPublishSourceDir(), lbrynetPublisher)
actionsRouter.HandleFunc("/publish", authenticator.Wrap(UploadHandler.Handle)) //.Headers(users.TokenHeader, "")
r.HandleFunc("/content/claims/{uri}/{claim}/{filename}", captureErrors(ContentByClaimsURI)).Methods("GET")
r.HandleFunc("/content/url", captureErrors(ContentByURL)).Methods("GET")
}
45 changes: 45 additions & 0 deletions api/routes_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
package api

import (
"bytes"
"net/http"
"net/http/httptest"
"testing"

"github.com/lbryio/lbrytv/app/proxy"
"github.com/lbryio/lbrytv/app/publish"
"github.com/lbryio/lbrytv/config"

"github.com/gorilla/mux"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)

func TestRoutesProxy(t *testing.T) {
r := mux.NewRouter()
proxy := proxy.NewService(config.GetLbrynet())

req, err := http.NewRequest("POST", "/api/v1/proxy", bytes.NewBuffer([]byte(`{"method": "status"}`)))
require.Nil(t, err)
rr := httptest.NewRecorder()

InstallRoutes(proxy, r)
r.ServeHTTP(rr, req)
assert.Equal(t, http.StatusOK, rr.Code)
assert.Contains(t, rr.Body.String(), `"result":`)
}

func TestRoutesPublish(t *testing.T) {
r := mux.NewRouter()
proxy := proxy.NewService(config.GetLbrynet())

req := publish.CreatePublishRequest(t, []byte("test file"))
rr := httptest.NewRecorder()

InstallRoutes(proxy, r)
r.ServeHTTP(rr, req)
assert.Equal(t, http.StatusOK, rr.Code)
// Authentication Required error here is enough to see that the request
// has been dispatched through the publish handler
assert.Contains(t, rr.Body.String(), `"code": -32080`)
}
8 changes: 4 additions & 4 deletions app/proxy/accounts_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@ func TestWithValidAuthToken(t *testing.T) {
r.Header.Add("X-Lbry-Auth-Token", "d94ab9865f8416d107935d2ca644509c")

rr := httptest.NewRecorder()
handler := NewRequestServer(svc)
handler := NewRequestHandler(svc)
handler.Handle(rr, r)
require.Equal(t, http.StatusOK, rr.Code)
err := json.Unmarshal(rr.Body.Bytes(), &response)
Expand Down Expand Up @@ -183,7 +183,7 @@ func TestWithValidAuthTokenConcurrent(t *testing.T) {
r.Header.Add("X-Lbry-Auth-Token", "d94ab9865f8416d107935d2ca644509c")

rr := httptest.NewRecorder()
handler := NewRequestServer(svc)
handler := NewRequestHandler(svc)
handler.Handle(rr, r)

require.Equal(t, http.StatusOK, rr.Code)
Expand Down Expand Up @@ -220,7 +220,7 @@ func TestWithWrongAuthToken(t *testing.T) {
r.Header.Add("X-Lbry-Auth-Token", "xXxXxXx")

rr := httptest.NewRecorder()
handler := NewRequestServer(svc)
handler := NewRequestHandler(svc)
handler.Handle(rr, r)

assert.Equal(t, http.StatusForbidden, rr.Code)
Expand Down Expand Up @@ -249,7 +249,7 @@ func TestWithoutToken(t *testing.T) {
r, _ := http.NewRequest("POST", proxySuffix, bytes.NewBuffer(qBody))

rr := httptest.NewRecorder()
handler := NewRequestServer(svc)
handler := NewRequestHandler(svc)
handler.Handle(rr, r)

require.Equal(t, http.StatusOK, rr.Code)
Expand Down
10 changes: 5 additions & 5 deletions app/proxy/handlers.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,17 +10,17 @@ import (
"github.com/lbryio/lbrytv/config"
)

// RequestServer is a wrapper for passing proxy.Service instance to proxy HTTP handler.
type RequestServer struct {
// RequestHandler is a wrapper for passing proxy.Service instance to proxy HTTP handler.
type RequestHandler struct {
*Service
}

func NewRequestServer(svc *Service) *RequestServer {
return &RequestServer{svc}
func NewRequestHandler(svc *Service) *RequestHandler {
return &RequestHandler{svc}
}

// Handle forwards client JSON-RPC request to proxy.
func (rh *RequestServer) Handle(w http.ResponseWriter, r *http.Request) {
func (rh *RequestHandler) Handle(w http.ResponseWriter, r *http.Request) {
var accountID string

if r.Method == "OPTIONS" {
Expand Down
8 changes: 4 additions & 4 deletions app/proxy/handlers_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ func TestProxyOptions(t *testing.T) {
r, _ := http.NewRequest("OPTIONS", "/api/proxy", nil)

rr := httptest.NewRecorder()
handler := NewRequestServer(svc)
handler := NewRequestHandler(svc)
handler.Handle(rr, r)

response := rr.Result()
Expand All @@ -27,7 +27,7 @@ func TestProxyNilQuery(t *testing.T) {
r, _ := http.NewRequest("POST", "/api/proxy", nil)

rr := httptest.NewRecorder()
handler := NewRequestServer(svc)
handler := NewRequestHandler(svc)
handler.Handle(rr, r)

assert.Equal(t, http.StatusBadRequest, rr.Code)
Expand All @@ -40,7 +40,7 @@ func TestProxyInvalidQuery(t *testing.T) {
r, _ := http.NewRequest("POST", "/api/proxy", bytes.NewBuffer([]byte("yo")))

rr := httptest.NewRecorder()
handler := NewRequestServer(svc)
handler := NewRequestHandler(svc)
handler.Handle(rr, r)

assert.Equal(t, http.StatusOK, rr.Code)
Expand All @@ -62,7 +62,7 @@ func TestProxy(t *testing.T) {
r, _ := http.NewRequest("POST", "/api/proxy", bytes.NewBuffer(queryBody))

rr := httptest.NewRecorder()
handler := NewRequestServer(svc)
handler := NewRequestHandler(svc)
handler.Handle(rr, r)

assert.Equal(t, http.StatusOK, rr.Code)
Expand Down
62 changes: 16 additions & 46 deletions app/publish/handler_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,33 +36,14 @@ func (p *DummyPublisher) Publish(filePath, accountID string, rawQuery []byte) []
}

func TestUploadHandler(t *testing.T) {
data := []byte("test file")
readSeeker := bytes.NewReader(data)
body := &bytes.Buffer{}

writer := multipart.NewWriter(body)

fileBody, err := writer.CreateFormFile(FileFieldName, "lbry_auto_test_file")
require.Nil(t, err)
_, err = io.Copy(fileBody, readSeeker)
require.Nil(t, err)

jsonPayload, err := writer.CreateFormField(JSONRPCFieldName)
require.Nil(t, err)
jsonPayload.Write([]byte(lbrynet.ExampleStreamCreateRequest))

writer.Close()

req, err := http.NewRequest("POST", "/", bytes.NewReader(body.Bytes()))
require.Nil(t, err)

req := CreatePublishRequest(t, []byte("test file"))
req.Header.Set(users.TokenHeader, "uPldrToken")
req.Header.Set("Content-Type", writer.FormDataContentType())

rr := httptest.NewRecorder()
authenticator := users.NewAuthenticator(&users.TestUserRetriever{AccountID: "UPldrAcc", Token: "uPldrToken"})
publisher := &DummyPublisher{}
pubHandler := NewUploadHandler(os.TempDir(), publisher)
pubHandler, err := NewUploadHandler(UploadOpts{Path: os.TempDir(), Publisher: publisher})
assert.Nil(t, err)

http.HandlerFunc(authenticator.Wrap(pubHandler.Handle)).ServeHTTP(rr, req)
response := rr.Result()
Expand All @@ -80,32 +61,13 @@ func TestUploadHandler(t *testing.T) {

func TestUploadHandlerAuthRequired(t *testing.T) {
var rpcResponse jsonrpc.RPCResponse

data := []byte("test file")
readSeeker := bytes.NewReader(data)
body := &bytes.Buffer{}

writer := multipart.NewWriter(body)

fileBody, err := writer.CreateFormFile(FileFieldName, "lbry_auto_test_file")
require.Nil(t, err)
io.Copy(fileBody, readSeeker)

jsonPayload, err := writer.CreateFormField(JSONRPCFieldName)
require.Nil(t, err)
jsonPayload.Write([]byte(lbrynet.ExampleStreamCreateRequest))

writer.Close()

req, err := http.NewRequest("POST", "/", bytes.NewReader(body.Bytes()))
require.Nil(t, err)

req.Header.Set("Content-Type", writer.FormDataContentType())
req := CreatePublishRequest(t, []byte("test file"))

rr := httptest.NewRecorder()
authenticator := users.NewAuthenticator(&users.TestUserRetriever{})
publisher := &DummyPublisher{}
pubHandler := NewUploadHandler(os.TempDir(), publisher)
pubHandler, err := NewUploadHandler(UploadOpts{Path: os.TempDir(), Publisher: publisher})
assert.Nil(t, err)

http.HandlerFunc(authenticator.Wrap(pubHandler.Handle)).ServeHTTP(rr, req)
response := rr.Result()
Expand All @@ -120,6 +82,7 @@ func TestUploadHandlerAuthRequired(t *testing.T) {
func TestUploadHandlerSystemError(t *testing.T) {
var rpcResponse jsonrpc.RPCResponse

// Creating POST data manually here because we need to avoid writer.Close()
data := []byte("test file")
readSeeker := bytes.NewReader(data)
body := &bytes.Buffer{}
Expand All @@ -134,7 +97,7 @@ func TestUploadHandlerSystemError(t *testing.T) {
require.Nil(t, err)
jsonPayload.Write([]byte(lbrynet.ExampleStreamCreateRequest))

// Not calling writer.Close() here to create unexpected EOF
// <--- Not calling writer.Close() here to create an unexpected EOF

req, err := http.NewRequest("POST", "/", bytes.NewReader(body.Bytes()))
require.Nil(t, err)
Expand All @@ -145,7 +108,8 @@ func TestUploadHandlerSystemError(t *testing.T) {
rr := httptest.NewRecorder()
authenticator := users.NewAuthenticator(&users.TestUserRetriever{AccountID: "UPldrAcc", Token: "uPldrToken"})
publisher := &DummyPublisher{}
pubHandler := NewUploadHandler(os.TempDir(), publisher)
pubHandler, err := NewUploadHandler(UploadOpts{Path: os.TempDir(), Publisher: publisher})
assert.Nil(t, err)

http.HandlerFunc(authenticator.Wrap(pubHandler.Handle)).ServeHTTP(rr, req)
response := rr.Result()
Expand All @@ -157,3 +121,9 @@ func TestUploadHandlerSystemError(t *testing.T) {
assert.Equal(t, "unexpected EOF", rpcResponse.Error.Message)
require.False(t, publisher.called)
}

func TestNewUploadHandler(t *testing.T) {
h, err := NewUploadHandler(UploadOpts{})
assert.Error(t, err, "need either a ProxyService or a Publisher instance")
assert.Nil(t, h)
}
Loading

0 comments on commit fbdc892

Please sign in to comment.