Skip to content

Commit

Permalink
Move proxy handlers and accounts tests into proxy package
Browse files Browse the repository at this point in the history
  • Loading branch information
anbsky committed Aug 14, 2019
1 parent ee0038b commit f575ed9
Show file tree
Hide file tree
Showing 5 changed files with 100 additions and 187 deletions.
61 changes: 1 addition & 60 deletions api/handlers.go
Original file line number Diff line number Diff line change
@@ -1,81 +1,22 @@
package api

import (
"encoding/json"
"fmt"
"io/ioutil"
"net/http"

"github.com/lbryio/lbrytv/app/player"
"github.com/lbryio/lbrytv/app/proxy"
"github.com/lbryio/lbrytv/app/users"
"github.com/lbryio/lbrytv/config"
"github.com/lbryio/lbrytv/internal/monitor"

"github.com/gorilla/mux"
log "github.com/sirupsen/logrus"
)

var logger = monitor.NewModuleLogger("api")

// Index just serves a blank home page
// Index serves a blank home page
func Index(w http.ResponseWriter, req *http.Request) {
w.WriteHeader(http.StatusOK)
}

// Proxy takes client request body and feeds it to the proxy module
func Proxy(w http.ResponseWriter, req *http.Request) {
var accountID string

if req.Method == "OPTIONS" {
w.WriteHeader(http.StatusOK)
return
}
if req.Body == nil {
w.WriteHeader(http.StatusBadRequest)
w.Write([]byte("empty request body"))
return
}

body, err := ioutil.ReadAll(req.Body)
if err != nil {
log.Panicf("error: %v", err.Error())
}

ur, err := proxy.UnmarshalRequest(body)
if err != nil {
response, _ := json.Marshal(proxy.NewErrorResponse(err.Error(), proxy.ErrProxy))
w.WriteHeader(http.StatusBadRequest)
w.Write(response)
return
}

if config.AccountsEnabled() {
accountID, err = users.GetAccountIDFromRequest(req)
if err != nil {
response, _ := json.Marshal(proxy.NewErrorResponse(err.Error(), proxy.ErrAuthFailed))
w.WriteHeader(http.StatusForbidden)
w.Write(response)
return
}
} else {
accountID = ""
}

lbrynetResponse, err := proxy.Proxy(ur, accountID)
if err != nil {
logger.LogF(monitor.F{"query": ur, "error": err}).Error("proxy errored")
response, _ := json.Marshal(proxy.NewErrorResponse(err.Error(), proxy.ErrProxy))
w.WriteHeader(http.StatusServiceUnavailable)
w.Write(response)
return
}

w.Header().Set("Content-Type", "application/json; charset=utf-8")
w.WriteHeader(http.StatusOK)
w.Write(lbrynetResponse)
}

func stream(uri string, w http.ResponseWriter, req *http.Request) {
err := player.PlayURI(uri, w, req)
// Only output error if player has not pushed anything to the client yet
Expand Down
66 changes: 4 additions & 62 deletions api/handlers_test.go
Original file line number Diff line number Diff line change
@@ -1,78 +1,20 @@
package api

import (
"bytes"
"encoding/json"
"io"
"net/http"
"net/http/httptest"
"strings"
"testing"

ljsonrpc "github.com/lbryio/lbry.go/extras/jsonrpc"
"github.com/stretchr/testify/assert"
"github.com/ybbus/jsonrpc"
)

func TestProxyOptions(t *testing.T) {
request, _ := http.NewRequest("OPTIONS", "/api/proxy", nil)
rr := httptest.NewRecorder()
http.HandlerFunc(Proxy).ServeHTTP(rr, request)
response := rr.Result()
assert.Equal(t, http.StatusOK, response.StatusCode)
}

func TestProxyNilQuery(t *testing.T) {
request, _ := http.NewRequest("POST", "/api/proxy", nil)
rr := httptest.NewRecorder()
http.HandlerFunc(Proxy).ServeHTTP(rr, request)
assert.Equal(t, http.StatusBadRequest, rr.Code)
assert.Equal(t, "empty request body", rr.Body.String())
}

func TestProxyInvalidQuery(t *testing.T) {
var parsedResponse jsonrpc.RPCResponse

request, _ := http.NewRequest("POST", "/api/proxy", bytes.NewBuffer([]byte("yo")))
rr := httptest.NewRecorder()
http.HandlerFunc(Proxy).ServeHTTP(rr, request)
assert.Equal(t, http.StatusBadRequest, rr.Code)
err := json.Unmarshal(rr.Body.Bytes(), &parsedResponse)
if err != nil {
panic(err)
}
assert.True(t, strings.HasPrefix(parsedResponse.Error.Message, "client json parse error: invalid character 'y'"))
}

func TestProxy(t *testing.T) {
var query *jsonrpc.RPCRequest
var queryBody []byte
var parsedResponse jsonrpc.RPCResponse
resolveResponse := make(ljsonrpc.ResolveResponse)

query = jsonrpc.NewRequest("resolve", map[string]string{"urls": "one"})
queryBody, _ = json.Marshal(query)
request, _ := http.NewRequest("POST", "/api/proxy", bytes.NewBuffer(queryBody))
rr := httptest.NewRecorder()

http.HandlerFunc(Proxy).ServeHTTP(rr, request)

assert.Equal(t, http.StatusOK, rr.Code)
assert.Equal(t, "application/json; charset=utf-8", rr.HeaderMap["Content-Type"][0])
err := json.Unmarshal(rr.Body.Bytes(), &parsedResponse)
if err != nil {
panic(err)
}
ljsonrpc.Decode(parsedResponse.Result, &resolveResponse)
assert.Equal(t, "one", resolveResponse["one"].Name)
}

func TestContentByURL_NoPayment(t *testing.T) {
req, _ := http.NewRequest("GET", "http://localhost:40080/content/url", nil)
req.URL.RawQuery = "pra-onde-vamos-em-2018-seguran-a-online#3a508cce1fda3b7c1a2502cb4323141d40a2cf0b"
req.Header.Add("Range", "bytes=0-1023")
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")
rr := httptest.NewRecorder()
http.HandlerFunc(ContentByURL).ServeHTTP(rr, req)
http.HandlerFunc(ContentByURL).ServeHTTP(rr, r)

assert.Equal(t, http.StatusPaymentRequired, rr.Code)
_, err := rr.Body.ReadByte()
Expand Down
23 changes: 18 additions & 5 deletions api/accounts_test.go → app/proxy/accounts_test.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package api
package proxy

import (
"bytes"
Expand All @@ -25,8 +25,13 @@ const dummyServerURL = "http://127.0.0.1:59999"
const proxySuffix = "/api/proxy"
const testSetupWait = 200 * time.Millisecond

var svc *Service

func TestMain(m *testing.M) {
// call flag.Parse() here if TestMain uses flags
go launchGrumpyServer()
svc = NewService(config.GetLbrynet())

config.Override("AccountsEnabled", true)
defer config.RestoreOverridden()

Expand All @@ -38,6 +43,7 @@ func TestMain(m *testing.M) {
}
c, connCleanup := storage.CreateTestConn(params)
c.SetDefaultConnection()

defer connCleanup()
defer lbrynet.RemoveAccount(dummyUserID)

Expand Down Expand Up @@ -117,7 +123,8 @@ func TestWithValidAuthToken(t *testing.T) {
r.Header.Add("X-Lbry-Auth-Token", "d94ab9865f8416d107935d2ca644509c")

rr := httptest.NewRecorder()
http.HandlerFunc(Proxy).ServeHTTP(rr, r)
handler := &RequestHandler{svc}
handler.Handle(rr, r)
require.Equal(t, http.StatusOK, rr.Code)
err := json.Unmarshal(rr.Body.Bytes(), &response)
require.Nil(t, err)
Expand Down Expand Up @@ -171,9 +178,11 @@ func TestWithValidAuthTokenConcurrent(t *testing.T) {
qBody, _ := json.Marshal(q)
r, _ := http.NewRequest("POST", proxySuffix, bytes.NewBuffer(qBody))
r.Header.Add("X-Lbry-Auth-Token", "d94ab9865f8416d107935d2ca644509c")

rr := httptest.NewRecorder()
handler := &RequestHandler{svc}
handler.Handle(rr, r)

http.HandlerFunc(Proxy).ServeHTTP(rr, r)
require.Equal(t, http.StatusOK, rr.Code)
json.Unmarshal(rr.Body.Bytes(), &response)
require.Nil(t, response.Error)
Expand Down Expand Up @@ -208,7 +217,9 @@ func TestWithWrongAuthToken(t *testing.T) {
r.Header.Add("X-Lbry-Auth-Token", "xXxXxXx")

rr := httptest.NewRecorder()
http.HandlerFunc(Proxy).ServeHTTP(rr, r)
handler := &RequestHandler{svc}
handler.Handle(rr, r)

assert.Equal(t, http.StatusForbidden, rr.Code)
err := json.Unmarshal(rr.Body.Bytes(), &response)
require.Nil(t, err)
Expand All @@ -235,7 +246,9 @@ func TestWithoutToken(t *testing.T) {
r, _ := http.NewRequest("POST", proxySuffix, bytes.NewBuffer(qBody))

rr := httptest.NewRecorder()
http.HandlerFunc(Proxy).ServeHTTP(rr, r)
handler := &RequestHandler{svc}
handler.Handle(rr, r)

require.Equal(t, http.StatusOK, rr.Code)
err := json.Unmarshal(rr.Body.Bytes(), &response)

Expand Down
76 changes: 76 additions & 0 deletions app/proxy/handlers_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
package proxy

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

ljsonrpc "github.com/lbryio/lbry.go/extras/jsonrpc"
"github.com/stretchr/testify/assert"
"github.com/ybbus/jsonrpc"
)

func TestProxyOptions(t *testing.T) {
r, _ := http.NewRequest("OPTIONS", "/api/proxy", nil)

rr := httptest.NewRecorder()
handler := &RequestHandler{svc}
handler.Handle(rr, r)

response := rr.Result()
assert.Equal(t, http.StatusOK, response.StatusCode)
}

func TestProxyNilQuery(t *testing.T) {
r, _ := http.NewRequest("POST", "/api/proxy", nil)

rr := httptest.NewRecorder()
handler := &RequestHandler{svc}
handler.Handle(rr, r)

assert.Equal(t, http.StatusBadRequest, rr.Code)
assert.Equal(t, "empty request body", rr.Body.String())
}

func TestProxyInvalidQuery(t *testing.T) {
var parsedResponse jsonrpc.RPCResponse

r, _ := http.NewRequest("POST", "/api/proxy", bytes.NewBuffer([]byte("yo")))

rr := httptest.NewRecorder()
handler := &RequestHandler{svc}
handler.Handle(rr, r)

assert.Equal(t, http.StatusOK, rr.Code)
err := json.Unmarshal(rr.Body.Bytes(), &parsedResponse)
if err != nil {
panic(err)
}
assert.Contains(t, parsedResponse.Error.Message, "invalid character 'y' looking for beginning of value")
}

func TestProxy(t *testing.T) {
var query *jsonrpc.RPCRequest
var queryBody []byte
var parsedResponse jsonrpc.RPCResponse
resolveResponse := make(ljsonrpc.ResolveResponse)

query = jsonrpc.NewRequest("resolve", map[string]string{"urls": "one"})
queryBody, _ = json.Marshal(query)
r, _ := http.NewRequest("POST", "/api/proxy", bytes.NewBuffer(queryBody))

rr := httptest.NewRecorder()
handler := &RequestHandler{svc}
handler.Handle(rr, r)

assert.Equal(t, http.StatusOK, rr.Code)
assert.Equal(t, "application/json; charset=utf-8", rr.HeaderMap["Content-Type"][0])
err := json.Unmarshal(rr.Body.Bytes(), &parsedResponse)
if err != nil {
panic(err)
}
ljsonrpc.Decode(parsedResponse.Result, &resolveResponse)
assert.Equal(t, "one", resolveResponse["one"].Name)
}
61 changes: 1 addition & 60 deletions app/proxy/proxy_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import (
"encoding/json"
"fmt"
"net/http"
"os"
"strings"
"sync"
"testing"
Expand Down Expand Up @@ -175,11 +174,6 @@ func call(t *testing.T, method string, params ...interface{}) jsonrpc.RPCRespons
return response
}

func TestMain(m *testing.M) {
go launchGrumpyServer()
os.Exit(m.Run())
}

// TestForwardCallWithHTTPError tests for HTTP level error connecting to a port that no server is listening on
func TestForwardCall_HTTPError(t *testing.T) {
config.Override("Lbrynet", "http://127.0.0.1:49999")
Expand Down Expand Up @@ -235,60 +229,7 @@ func TestUnmarshalRequest(t *testing.T) {
assert.True(t, strings.HasPrefix(err.Error(), "client json parse error: invalid character 'y'"))
}

func TestForwardCall(t *testing.T) {
var err error
var query *jsonrpc.RPCRequest
var response jsonrpc.RPCResponse
var rawResponse []byte

streamURI := "what#6769855a9aa43b67086f9ff3c1a5bacb5698a27a"
query = jsonrpc.NewRequest(methodResolve, map[string]string{paramUrls: streamURI})
queryBody, _ := json.Marshal(query)
query, err = UnmarshalRequest(queryBody)
rawResponse, err = ForwardCall(*query)
if err != nil {
t.Errorf("failed with an unexpected error: %v", err)
return
} else if response.Error != nil {
t.Errorf("daemon errored: %v", response.Error.Message)
return
}

query = jsonrpc.NewRequest(methodGet, map[string]string{"uri": streamURI})
_, err = ForwardCall(*query)
if err != nil {
t.Errorf("failed with an unexpected error: %v", err)
return
}
if response.Error != nil {
t.Errorf("daemon errored: %v", response.Error.Message)
return
}

var resolveResponse *ljsonrpc.ResolveResponse
json.Unmarshal(rawResponse, &response)
response.GetObject(&resolveResponse)
outpoint := fmt.Sprintf("%v:%v", (*resolveResponse)[streamURI].Txid, 0)

query = jsonrpc.NewRequest(methodFileList, map[string]string{"outpoint": outpoint})
rawResponse, err = ForwardCall(*query)
if err != nil {
t.Errorf("file_list of outpoint %v failed with an unexpected error: %v", outpoint, err)
return
}

var fileListResponse *ljsonrpc.FileListResponse
json.Unmarshal(rawResponse, &response)
assert.Nil(t, response.Error)
response.GetObject(&fileListResponse)

if len(*fileListResponse) == 0 {
t.Errorf("not enough results, daemon responded with %v", fileListResponse)
return
}
}

func TesProxy_WithCache(t *testing.T) {
func TesProxyWithCache(t *testing.T) {
var (
err error
query *jsonrpc.RPCRequest
Expand Down

0 comments on commit f575ed9

Please sign in to comment.