Commit 315356ed authored by Jacob Vosmaer's avatar Jacob Vosmaer

Move upload handling into internal/upload

parent 39b50833
......@@ -5,23 +5,35 @@ import (
"bytes"
"fmt"
"io/ioutil"
"log"
"net/http"
"net/http/httputil"
"net/url"
"sync"
)
type Proxy struct {
reverseProxy *httputil.ReverseProxy
version string
URL string
Version string
Transport http.RoundTripper
_reverseProxy *httputil.ReverseProxy
configureReverseProxyOnce sync.Once
}
func NewProxy(url *url.URL, transport http.RoundTripper, version string) *Proxy {
func (p *Proxy) reverseProxy() *httputil.ReverseProxy {
p.configureReverseProxyOnce.Do(p.configureReverseProxy)
return p._reverseProxy
}
func (p *Proxy) configureReverseProxy() {
// Modify a copy of url
proxyURL := *url
proxyURL.Path = ""
p := Proxy{reverseProxy: httputil.NewSingleHostReverseProxy(&proxyURL), version: version}
p.reverseProxy.Transport = transport
return &p
url, err := url.Parse(p.URL)
if err != nil {
log.Fatalf("configureReverseProxy: %v", err)
}
url.Path = ""
p._reverseProxy = httputil.NewSingleHostReverseProxy(url)
p._reverseProxy.Transport = p.Transport
}
type RoundTripper struct {
......@@ -78,9 +90,9 @@ func (p *Proxy) ServeHTTP(w http.ResponseWriter, r *http.Request) {
req.Header = HeaderClone(r.Header)
// Set Workhorse version
req.Header.Set("Gitlab-Workhorse", p.version)
req.Header.Set("Gitlab-Workhorse", p.Version)
rw := newSendFileResponseWriter(w, &req)
defer rw.Flush()
p.reverseProxy.ServeHTTP(&rw, &req)
p.reverseProxy().ServeHTTP(&rw, &req)
}
package upstream
package upload
import (
"../api"
"net/http"
)
func artifactsAuthorizeHandler(myAPI *api.API, h http.HandlerFunc) http.HandlerFunc {
func Artifacts(myAPI *api.API, h http.Handler) http.Handler {
return myAPI.PreAuthorizeHandler(func(w http.ResponseWriter, r *http.Request, a *api.Response) {
r.Header.Set(tempPathHeader, a.TempPath)
h(w, r)
h.ServeHTTP(w, r)
}, "/authorize")
}
package upstream
package upload
import (
"../helper"
......
package upstream
package upload
import (
"../helper"
"../proxy"
"bytes"
"fmt"
"io"
......@@ -13,7 +14,6 @@ import (
"regexp"
"strings"
"testing"
"time"
)
var nilHandler = http.HandlerFunc(func(http.ResponseWriter, *http.Request) {})
......@@ -40,6 +40,7 @@ func TestUploadHandlerForwardingRawData(t *testing.T) {
w.WriteHeader(202)
fmt.Fprint(w, "RESPONSE")
})
defer ts.Close()
httpRequest, err := http.NewRequest("PATCH", ts.URL+"/url/path", bytes.NewBufferString("REQUEST"))
if err != nil {
......@@ -56,7 +57,7 @@ func TestUploadHandlerForwardingRawData(t *testing.T) {
httpRequest.Header.Set(tempPathHeader, tempPath)
handleFileUploads(New(ts.URL, "", "123", time.Second).Proxy).ServeHTTP(response, httpRequest)
handleFileUploads(&proxy.Proxy{URL: ts.URL, Version: "123"}).ServeHTTP(response, httpRequest)
helper.AssertResponseCode(t, response, 202)
if response.Body.String() != "RESPONSE" {
t.Fatal("Expected RESPONSE in response body")
......@@ -129,9 +130,8 @@ func TestUploadHandlerRewritingMultiPartData(t *testing.T) {
httpRequest.Header.Set("Content-Type", writer.FormDataContentType())
httpRequest.Header.Set(tempPathHeader, tempPath)
response := httptest.NewRecorder()
u := New(ts.URL, "", "123", time.Second)
handleFileUploads(u.Proxy).ServeHTTP(response, httpRequest)
handleFileUploads(&proxy.Proxy{URL: ts.URL, Version: "123"}).ServeHTTP(response, httpRequest)
helper.AssertResponseCode(t, response, 202)
if _, err := os.Stat(filePath); !os.IsNotExist(err) {
......
......@@ -4,6 +4,7 @@ import (
"../errorpage"
"../git"
"../lfs"
"../upload"
"net/http"
"regexp"
)
......@@ -50,7 +51,7 @@ func (u *Upstream) compileRoutes() {
route{"GET", regexp.MustCompile(projectsAPIPattern + `repository/archive.tar.bz2\z`), git.GetArchive(u.API)},
// CI Artifacts API
route{"POST", regexp.MustCompile(ciAPIPattern + `v1/builds/[0-9]+/artifacts\z`), contentEncodingHandler(artifactsAuthorizeHandler(u.API, handleFileUploads(u.Proxy)))},
route{"POST", regexp.MustCompile(ciAPIPattern + `v1/builds/[0-9]+/artifacts\z`), contentEncodingHandler(upload.Artifacts(u.API, u.Proxy))},
// Explicitly u.Proxy API requests
route{"", regexp.MustCompile(apiPattern), u.Proxy},
......
......@@ -64,7 +64,7 @@ func New(authBackend string, authSocket string, version string, responseHeadersT
URL: parsedURL,
Version: version,
},
Proxy: proxy.NewProxy(parsedURL, proxyTransport, version),
Proxy: &proxy.Proxy{URL: authBackend, Transport: proxyTransport, Version: version},
urlPrefix: urlPrefix(relativeURLRoot),
}
up.compileRoutes()
......
......@@ -10,7 +10,6 @@ import (
"net"
"net/http"
"net/http/httptest"
"net/url"
"regexp"
"testing"
"time"
......@@ -94,15 +93,10 @@ func TestProxyReadTimeout(t *testing.T) {
},
)
u := newUpstream(ts.URL)
url, err := url.Parse(ts.URL)
if err != nil {
t.Fatal(err)
}
u.Proxy = proxy.NewProxy(url, transport, "123")
p := &proxy.Proxy{URL: ts.URL, Transport: transport, Version: "123"}
w := httptest.NewRecorder()
u.Proxy.ServeHTTP(w, httpRequest)
p.ServeHTTP(w, httpRequest)
helper.AssertResponseCode(t, w, 502)
helper.AssertResponseBody(t, w, "net/http: timeout awaiting response headers")
}
......
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