good morning!!!!

Skip to content
Snippets Groups Projects
Commit c074cc6b authored by a's avatar a
Browse files

http

parent 6f0e71b0
Branches
Tags
1 merge request!15Draft: V2
Showing
with 160 additions and 42 deletions
package codecs
import "gfx.cafe/open/jrpc/pkg/codec/codecs/inproc"
var NewInProc = inproc.NewCodec
// Copyright 2016 The go-ethereum Authors package http
// This file is part of the go-ethereum library.
//
// The go-ethereum library is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// The go-ethereum library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
package jrpc
import ( import (
"bytes" "bytes"
"context" "context"
"encoding/json" "encoding/json"
"errors" "errors"
"gfx.cafe/open/jrpc/pkg/clientutil"
"gfx.cafe/open/jrpc/pkg/codec"
"net/http" "net/http"
"sync/atomic" "sync/atomic"
"time" "time"
"gfx.cafe/open/jrpc/pkg/clientutil"
"gfx.cafe/open/jrpc/pkg/codec"
"gfx.cafe/open/jrpc" "gfx.cafe/open/jrpc"
) )
...@@ -44,6 +29,8 @@ const ( ...@@ -44,6 +29,8 @@ const (
subscribeTimeout = 5 * time.Second // overall timeout eth_subscribe, rpc_modules calls subscribeTimeout = 5 * time.Second // overall timeout eth_subscribe, rpc_modules calls
) )
var _ jrpc.Conn = (*Client)(nil)
// Client represents a connection to an RPC server. // Client represents a connection to an RPC server.
type Client struct { type Client struct {
remote string remote string
...@@ -86,7 +73,7 @@ func (c *Client) Do(ctx context.Context, result any, method string, params any) ...@@ -86,7 +73,7 @@ func (c *Client) Do(ctx context.Context, result any, method string, params any)
return nil return nil
} }
func (c *Client) Notify(ctx context.Context, result any, method string, params any) error { func (c *Client) Notify(ctx context.Context, method string, params any) error {
req := jrpc.NewRequestInt(ctx, int(c.id.Add(1)), method, params) req := jrpc.NewRequestInt(ctx, int(c.id.Add(1)), method, params)
dat, err := req.MarshalJSON() dat, err := req.MarshalJSON()
if err != nil { if err != nil {
......
// Copyright 2016 The go-ethereum Authors package http
// This file is part of the go-ethereum library.
//
// The go-ethereum library is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// The go-ethereum library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
package jrpc
import ( import (
"context" "context"
......
package http
import (
"context"
"encoding/base64"
"encoding/json"
"errors"
"io"
"net/http"
"net/url"
"gfx.cafe/open/jrpc"
"gfx.cafe/open/jrpc/pkg/codec"
)
type Codec struct {
ctx context.Context
cn func()
r *http.Request
w http.ResponseWriter
msgs chan json.RawMessage
errs chan error
}
func NewCodec(r *http.Request, w http.ResponseWriter) *Codec {
ctx, cn := context.WithCancel(r.Context())
c := &Codec{
ctx: ctx,
cn: cn,
r: r,
w: w,
msgs: make(chan json.RawMessage, 1),
errs: make(chan error, 1),
}
go c.doRead()
return c
}
// gets the peer info
func (c *Codec) PeerInfo() codec.PeerInfo {
ci := codec.PeerInfo{
Transport: "http",
RemoteAddr: c.r.RemoteAddr,
HTTP: codec.HttpInfo{
Version: c.r.Proto,
UserAgent: c.r.UserAgent(),
Host: c.r.Host,
Headers: c.r.Header.Clone(),
},
}
ci.HTTP.Origin = c.r.Header.Get("X-Real-Ip")
if ci.HTTP.Origin == "" {
ci.HTTP.Origin = c.r.Header.Get("X-Forwarded-For")
}
if ci.HTTP.Origin == "" {
ci.HTTP.Origin = c.r.Header.Get("Origin")
}
if ci.HTTP.Origin == "" {
ci.HTTP.Origin = c.r.RemoteAddr
}
return ci
}
func (r *Codec) doReadGet() (msgs json.RawMessage, err error) {
method_up := r.r.URL.Query().Get("method")
params, _ := url.QueryUnescape(r.r.URL.Query().Get("params"))
param := []byte(params)
if pb, err := base64.URLEncoding.DecodeString(params); err == nil {
param = pb
}
id := r.r.URL.Query().Get("id")
if id == "" {
id = "1"
}
req := jrpc.NewRequest(r.ctx, id, method_up, json.RawMessage(param))
return req.MarshalJSON()
}
var ErrInvalidContentType = errors.New("invalid content type")
func (c *Codec) doRead() {
contentMatches := true
types := c.r.Header.Values("content-type")
for _, v := range types {
// TODO: check content type
_ = v
}
if !contentMatches {
c.errs <- ErrInvalidContentType
return
}
var data json.RawMessage
var err error
// TODO: implement eventsource
switch c.r.Method {
case http.MethodGet:
data, err = c.doReadGet()
return
case http.MethodPost:
data, err = io.ReadAll(c.r.Body)
}
if err != nil {
c.errs <- err
return
}
c.msgs <- data
}
// json.RawMessage can be an array of requests. if it is, then it is a batch request
func (c *Codec) ReadBatch(ctx context.Context) (msgs json.RawMessage, err error) {
select {
case ans := <-c.msgs:
return ans, nil
case err := <-c.errs:
return nil, err
case <-ctx.Done():
return nil, ctx.Err()
case <-c.ctx.Done():
return nil, c.ctx.Err()
}
}
// closes the connection
func (c *Codec) Close() error {
c.cn()
return nil
}
func (c *Codec) Write(p []byte) (n int, err error) {
return c.w.Write(p)
}
// Closed returns a channel which is closed when the connection is closed.
func (c *Codec) Closed() <-chan struct{} {
return c.ctx.Done()
}
// RemoteAddr returns the peer address of the connection.
func (c *Codec) RemoteAddr() string {
return ""
}
...@@ -14,7 +14,7 @@ ...@@ -14,7 +14,7 @@
// You should have received a copy of the GNU Lesser General Public License // You should have received a copy of the GNU Lesser General Public License
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>. // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
package jrpc package http
import ( import (
"net/http" "net/http"
......
File moved
File moved
...@@ -2,7 +2,7 @@ package inproc_test ...@@ -2,7 +2,7 @@ package inproc_test
import ( import (
"context" "context"
inproc2 "gfx.cafe/open/jrpc/pkg/codec/inproc" "gfx.cafe/open/jrpc/pkg/codec/codecs/inproc"
"gfx.cafe/open/jrpc/pkg/jmux" "gfx.cafe/open/jrpc/pkg/jmux"
"testing" "testing"
...@@ -16,8 +16,8 @@ func TestInprocSetup(t *testing.T) { ...@@ -16,8 +16,8 @@ func TestInprocSetup(t *testing.T) {
ctx := context.Background() ctx := context.Background()
clientCodec := inproc2.NewCodec() clientCodec := inproc.NewCodec()
client := inproc2.NewClient(clientCodec, nil) client := inproc.NewClient(clientCodec, nil)
go func() { go func() {
srv.ServeCodec(ctx, clientCodec) srv.ServeCodec(ctx, clientCodec)
}() }()
......
File moved
File moved
File moved
File moved
File moved
File moved
File moved
File moved
...@@ -5,7 +5,7 @@ import ( ...@@ -5,7 +5,7 @@ import (
"encoding/base64" "encoding/base64"
"encoding/json" "encoding/json"
codec2 "gfx.cafe/open/jrpc/pkg/codec" codec2 "gfx.cafe/open/jrpc/pkg/codec"
"gfx.cafe/open/jrpc/pkg/codec/websocket/wsjson" "gfx.cafe/open/jrpc/pkg/codec/codecs/websocket/wsjson"
"net/http" "net/http"
"net/url" "net/url"
"time" "time"
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment