Conver to regular Go vendor + dep tool

This commit is contained in:
Andrey Smirnov
2017-03-22 17:38:32 +03:00
parent 070347295e
commit c6c1012330
3260 changed files with 1742550 additions and 72 deletions
+23
View File
@@ -0,0 +1,23 @@
# Compiled Object files, Static and Dynamic libs (Shared Objects)
*.o
*.a
*.so
# Folders
_obj
_test
# Architecture specific extensions/prefixes
*.[568vq]
[568vq].out
*.cgo1.go
*.cgo2.c
_cgo_defun.c
_cgo_gotypes.go
_cgo_export.*
_testmain.go
*.exe
*.test
+21
View File
@@ -0,0 +1,21 @@
The MIT License (MIT)
Copyright (c) 2014 Andrey Smirnov
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
+23
View File
@@ -0,0 +1,23 @@
go-ftp-protocol
===============
Plugin for http.Transport with support for ftp:// protocol in Go.
Limitations: only anonymous FTP servers, only file retrieval operations.
Internally connections to FTP servers are cached and re-used when possible.
Example usage:
import "github.com/smira/go-ftp-protocol/protocol"
transport := &http.Transport{}
transport.RegisterProtocol("ftp", &protocol.FTPRoundTripper{})
client := &http.Client{Transport: transport}
resp, err := client.Get("ftp://ftp.ru.debian.org/debian/README")
License: MIT
Base on FTP client library: http://github.com/jlaffaye/ftp/
+152
View File
@@ -0,0 +1,152 @@
// Package protocol implements ftp:// scheme plugin for http.Transport
//
// github.com/jlaffaye/ftp library is used internally as FTP client implementation.
//
// Limitations: only anonymous FTP servers, only file retrieval operations.
//
// Internally connections to FTP servers are cached and re-used when possible.
//
// Example:
//
// transport := &http.Transport{}
// transport.RegisterProtocol("ftp", &FTPRoundTripper{})
// client := &http.Client{Transport: transport}
// resp, err := client.Get("ftp://ftp.ru.debian.org/debian/README")
package protocol
import (
"fmt"
"github.com/jlaffaye/ftp"
"io"
"net/http"
"net/textproto"
"strings"
"sync"
)
// FTPRoundTripper is an implementation of net/http.RoundTripper on top of FTP client
type FTPRoundTripper struct {
lock sync.Mutex
idleConnections map[string][]*ftp.ServerConn
}
// verify interface
var (
_ http.RoundTripper = &FTPRoundTripper{}
)
type readCloserWrapper struct {
body io.ReadCloser
rt *FTPRoundTripper
hostport string
conn *ftp.ServerConn
}
func (w *readCloserWrapper) Read(p []byte) (n int, err error) {
return w.body.Read(p)
}
func (w *readCloserWrapper) Close() error {
err := w.body.Close()
if err == nil {
w.rt.putConnection(w.hostport, w.conn)
}
return err
}
func (rt *FTPRoundTripper) getConnection(hostport string) (conn *ftp.ServerConn, err error) {
rt.lock.Lock()
conns, ok := rt.idleConnections[hostport]
if ok && len(conns) > 0 {
conn = conns[0]
rt.idleConnections[hostport] = conns[1:]
rt.lock.Unlock()
return
}
rt.lock.Unlock()
conn, err = ftp.Connect(hostport)
if err != nil {
return nil, err
}
err = conn.Login("anonymous", "anonymous")
if err != nil {
conn.Quit()
return nil, err
}
return conn, nil
}
func (rt *FTPRoundTripper) putConnection(hostport string, conn *ftp.ServerConn) {
rt.lock.Lock()
defer rt.lock.Unlock()
if rt.idleConnections == nil {
rt.idleConnections = make(map[string][]*ftp.ServerConn)
}
rt.idleConnections[hostport] = append(rt.idleConnections[hostport], conn)
}
// RoundTrip parses incoming GET "HTTP" request and transforms it into
// commands to ftp client
func (rt *FTPRoundTripper) RoundTrip(request *http.Request) (*http.Response, error) {
if request.URL.Scheme != "ftp" {
return nil, fmt.Errorf("only ftp protocol is supported, got %s", request.Proto)
}
if request.Method != "GET" {
return nil, fmt.Errorf("only GET method is supported, got %s", request.Method)
}
hostport := request.URL.Host
if strings.Index(hostport, ":") == -1 {
hostport = hostport + ":21"
}
connection, err := rt.getConnection(hostport)
if err != nil {
return nil, err
}
var body io.ReadCloser
body, err = connection.Retr(request.URL.Path)
if err != nil {
if te, ok := err.(*textproto.Error); ok {
rt.putConnection(hostport, connection)
if te.Code == ftp.StatusFileUnavailable {
return &http.Response{
Status: "404 Not Found",
StatusCode: 404,
Proto: "FTP/1.0",
ProtoMajor: 1,
ProtoMinor: 0,
Request: request,
}, nil
}
}
return nil, err
}
return &http.Response{
Status: "200 OK",
StatusCode: 200,
Proto: "FTP/1.0",
ProtoMajor: 1,
ProtoMinor: 0,
Body: &readCloserWrapper{
body: body,
rt: rt,
hostport: hostport,
conn: connection,
},
ContentLength: -1,
Request: request,
}, nil
}
+94
View File
@@ -0,0 +1,94 @@
package protocol
import (
"io/ioutil"
"net/http"
"strings"
"testing"
)
func TestProtocol(t *testing.T) {
transport := &http.Transport{}
transport.RegisterProtocol("ftp", &FTPRoundTripper{})
client := &http.Client{Transport: transport}
resp, err := client.Get("ftp://ftp.ru.debian.org/debian/README")
if err != nil {
t.Fatal(err)
}
if resp.StatusCode != 200 {
t.Fatalf("resp.StatusCode 200 != %d", resp.StatusCode)
}
content, err := ioutil.ReadAll(resp.Body)
if err != nil {
t.Fatal(err)
}
err = resp.Body.Close()
if err != nil {
t.Fatal(err)
}
if !strings.HasPrefix(string(content), "See http://www.debian.org/ for information about Debian GNU/Linux.") {
t.Fatalf("unexpected content: %s", content)
}
resp, err = client.Get("ftp://ftp.ru.debian.org/debian/missing")
if err != nil {
t.Fatal(err)
}
if resp.StatusCode != 404 {
t.Fatalf("resp.StatusCode 404 != %d", resp.StatusCode)
}
}
func TestConcurrent(t *testing.T) {
transport := &http.Transport{}
transport.RegisterProtocol("ftp", &FTPRoundTripper{})
client := &http.Client{Transport: transport}
const concurrency = 4
const count = 10
done := make(chan struct{}, concurrency)
for i := 0; i < concurrency; i++ {
go func() {
defer func() { done <- struct{}{} }()
for j := 0; j < 10; j++ {
resp, err := client.Get("ftp://ftp.ru.debian.org/debian/README")
if err != nil {
t.Fatal(err)
}
if resp.StatusCode != 200 {
t.Fatalf("resp.StatusCode 200 != %d", resp.StatusCode)
}
content, err := ioutil.ReadAll(resp.Body)
if err != nil {
t.Fatal(err)
}
err = resp.Body.Close()
if err != nil {
t.Fatal(err)
}
if !strings.HasPrefix(string(content), "See http://www.debian.org/ for information about Debian GNU/Linux.") {
t.Fatalf("unexpected content: %s", content)
}
}
}()
}
for i := 0; i < concurrency; i++ {
<-done
}
}