Unverified Commit 7b6903f8 authored by Marco Munizaga's avatar Marco Munizaga Committed by GitHub

Merge pull request #246 from multiformats/marco/http-path

Add support for http-path
parents 5d767c57 d31f3765
...@@ -192,6 +192,11 @@ var good = []string{ ...@@ -192,6 +192,11 @@ var good = []string{
"/ip4/127.0.0.1/tcp/127/wss", "/ip4/127.0.0.1/tcp/127/wss",
"/ip4/127.0.0.1/tcp/127/webrtc-direct", "/ip4/127.0.0.1/tcp/127/webrtc-direct",
"/ip4/127.0.0.1/tcp/127/webrtc", "/ip4/127.0.0.1/tcp/127/webrtc",
"/http-path/tmp%2Fbar",
"/http-path/tmp%2Fbar%2Fbaz",
"/http-path/foo",
"/ip4/127.0.0.1/tcp/0/p2p/12D3KooWCryG7Mon9orvQxcS1rYZjotPgpwoJNHHKcLLfE4Hf5mV/http-path/foo",
"/ip4/127.0.0.1/tcp/443/tls/sni/example.com/http/http-path/foo",
} }
func TestConstructSucceeds(t *testing.T) { func TestConstructSucceeds(t *testing.T) {
...@@ -627,6 +632,7 @@ func TestRoundTrip(t *testing.T) { ...@@ -627,6 +632,7 @@ func TestRoundTrip(t *testing.T) {
"/ip4/127.0.0.1/udp/1234/quic-v1/webtransport/certhash/uEiDDq4_xNyDorZBH3TlGazyJdOWSwvo4PUo5YHFMrvDE8g", "/ip4/127.0.0.1/udp/1234/quic-v1/webtransport/certhash/uEiDDq4_xNyDorZBH3TlGazyJdOWSwvo4PUo5YHFMrvDE8g",
"/p2p/QmbHVEEepCi7rn7VL7Exxpd2Ci9NNB6ifvqwhsrbRMgQFP", "/p2p/QmbHVEEepCi7rn7VL7Exxpd2Ci9NNB6ifvqwhsrbRMgQFP",
"/p2p/QmbHVEEepCi7rn7VL7Exxpd2Ci9NNB6ifvqwhsrbRMgQFP/unix/a/b/c", "/p2p/QmbHVEEepCi7rn7VL7Exxpd2Ci9NNB6ifvqwhsrbRMgQFP/unix/a/b/c",
"/http-path/tmp%2Fbar",
} { } {
ma, err := NewMultiaddr(s) ma, err := NewMultiaddr(s)
if err != nil { if err != nil {
...@@ -923,3 +929,48 @@ func TestDNS(t *testing.T) { ...@@ -923,3 +929,48 @@ func TestDNS(t *testing.T) {
t.Fatal("expected equality") t.Fatal("expected equality")
} }
} }
func TestHTTPPath(t *testing.T) {
t.Run("bad addr", func(t *testing.T) {
badAddr := "/http-path/thisIsMissingAfullByte%f"
_, err := NewMultiaddr(badAddr)
require.Error(t, err)
})
t.Run("only reads the http-path part", func(t *testing.T) {
addr := "/http-path/tmp%2Fbar/p2p-circuit" // The http-path only reference the part immediately after it. It does not include the rest of the multiaddr (like the /path component sometimes does)
m, err := NewMultiaddr(addr)
require.NoError(t, err)
m.ValueForProtocol(P_HTTP_PATH)
v, err := m.ValueForProtocol(P_HTTP_PATH)
require.NoError(t, err)
require.Equal(t, "tmp%2Fbar", v)
})
t.Run("round trip", func(t *testing.T) {
cases := []string{
"/http-path/tmp%2Fbar",
"/http-path/tmp%2Fbar%2Fbaz",
"/http-path/foo",
"/ip4/127.0.0.1/tcp/0/p2p/12D3KooWCryG7Mon9orvQxcS1rYZjotPgpwoJNHHKcLLfE4Hf5mV/http-path/foo",
"/ip4/127.0.0.1/tcp/443/tls/sni/example.com/http/http-path/foo",
}
for _, c := range cases {
m, err := NewMultiaddr(c)
require.NoError(t, err)
require.Equal(t, c, m.String())
}
})
t.Run("value for protocol", func(t *testing.T) {
m := StringCast("/http-path/tmp%2Fbar")
v, err := m.ValueForProtocol(P_HTTP_PATH)
require.NoError(t, err)
// This gives us the url escaped version
require.Equal(t, "tmp%2Fbar", v)
// If we want the raw unescaped version, we can use the component and read it
_, component := SplitLast(m)
require.Equal(t, "tmp/bar", string(component.RawValue()))
})
}
...@@ -26,6 +26,7 @@ const ( ...@@ -26,6 +26,7 @@ const (
P_P2P = 421 P_P2P = 421
P_IPFS = P_P2P // alias for backwards compatibility P_IPFS = P_P2P // alias for backwards compatibility
P_HTTP = 480 P_HTTP = 480
P_HTTP_PATH = 481
P_HTTPS = 443 // deprecated alias for /tls/http P_HTTPS = 443 // deprecated alias for /tls/http
P_ONION = 444 // also for backwards compatibility P_ONION = 444 // also for backwards compatibility
P_ONION3 = 445 P_ONION3 = 445
...@@ -206,6 +207,13 @@ var ( ...@@ -206,6 +207,13 @@ var (
Code: P_HTTP, Code: P_HTTP,
VCode: CodeToVarint(P_HTTP), VCode: CodeToVarint(P_HTTP),
} }
protoHTTPPath = Protocol{
Name: "http-path",
Code: P_HTTP_PATH,
VCode: CodeToVarint(P_HTTP_PATH),
Size: LengthPrefixedVarSize,
Transcoder: TranscoderHTTPPath,
}
protoHTTPS = Protocol{ protoHTTPS = Protocol{
Name: "https", Name: "https",
Code: P_HTTPS, Code: P_HTTPS,
...@@ -301,6 +309,7 @@ func init() { ...@@ -301,6 +309,7 @@ func init() {
protoWEBTRANSPORT, protoWEBTRANSPORT,
protoCERTHASH, protoCERTHASH,
protoHTTP, protoHTTP,
protoHTTPPath,
protoHTTPS, protoHTTPS,
protoP2P, protoP2P,
protoUNIX, protoUNIX,
......
...@@ -8,6 +8,7 @@ import ( ...@@ -8,6 +8,7 @@ import (
"errors" "errors"
"fmt" "fmt"
"net" "net"
"net/url"
"strconv" "strconv"
"strings" "strings"
...@@ -454,3 +455,30 @@ func validateCertHash(b []byte) error { ...@@ -454,3 +455,30 @@ func validateCertHash(b []byte) error {
_, err := mh.Decode(b) _, err := mh.Decode(b)
return err return err
} }
var TranscoderHTTPPath = NewTranscoderFromFunctions(httpPathStB, httpPathBtS, validateHTTPPath)
func httpPathStB(s string) ([]byte, error) {
unescaped, err := url.QueryUnescape(s)
if err != nil {
return nil, err
}
if len(unescaped) == 0 {
return nil, fmt.Errorf("empty http path is not allowed")
}
return []byte(unescaped), err
}
func httpPathBtS(b []byte) (string, error) {
if len(b) == 0 {
return "", fmt.Errorf("empty http path is not allowed")
}
return url.QueryEscape(string(b)), nil
}
func validateHTTPPath(b []byte) error {
if len(b) == 0 {
return fmt.Errorf("empty http path is not allowed")
}
return nil // We can represent any byte slice when we escape it.
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment