2015-03-28 22:07:40 +00:00
|
|
|
package proxy
|
|
|
|
|
|
|
|
import (
|
|
|
|
"io"
|
|
|
|
"mime"
|
|
|
|
"net/http"
|
|
|
|
)
|
|
|
|
|
|
|
|
type ResponseReader struct {
|
|
|
|
io.Reader
|
|
|
|
r *http.Response
|
|
|
|
}
|
|
|
|
|
|
|
|
func newResponseReader(r *http.Response) *ResponseReader {
|
|
|
|
return &ResponseReader{
|
|
|
|
Reader: r.Body,
|
|
|
|
r: r,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func (r *ResponseReader) ContentType() string {
|
|
|
|
cth := r.Header().Get("Content-Type")
|
|
|
|
ct, _, _ := mime.ParseMediaType(cth)
|
|
|
|
return ct
|
|
|
|
}
|
|
|
|
|
|
|
|
func (r *ResponseReader) Header() http.Header {
|
|
|
|
return r.r.Header
|
|
|
|
}
|
|
|
|
|
|
|
|
func (r *ResponseReader) Request() *http.Request {
|
|
|
|
return r.r.Request
|
|
|
|
}
|
|
|
|
|
|
|
|
type ResponseWriter struct {
|
|
|
|
io.Writer
|
|
|
|
rw http.ResponseWriter
|
|
|
|
statusCode int
|
|
|
|
headersDone bool
|
|
|
|
}
|
|
|
|
|
|
|
|
func newResponseWriter(w http.ResponseWriter) *ResponseWriter {
|
|
|
|
return &ResponseWriter{
|
|
|
|
Writer: w,
|
|
|
|
rw: w,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func (w *ResponseWriter) takeHeaders(r *ResponseReader) {
|
|
|
|
for k, v := range r.Header() {
|
|
|
|
for _, v := range v {
|
|
|
|
w.Header().Add(k, v)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
w.WriteHeader(r.r.StatusCode)
|
|
|
|
}
|
|
|
|
|
|
|
|
func (w *ResponseWriter) Header() http.Header {
|
|
|
|
return w.rw.Header()
|
|
|
|
}
|
|
|
|
|
2015-03-29 14:09:48 +00:00
|
|
|
func (w *ResponseWriter) WriteHeader(s int) {
|
|
|
|
w.statusCode = s
|
2015-03-28 22:07:40 +00:00
|
|
|
}
|
|
|
|
|
2015-03-29 14:09:48 +00:00
|
|
|
func (w *ResponseWriter) ReadFrom(r io.Reader) error {
|
|
|
|
w.flushHeaders()
|
|
|
|
_, err := io.Copy(w.Writer, r)
|
|
|
|
return err
|
2015-03-28 22:07:40 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func (w *ResponseWriter) Write(b []byte) (int, error) {
|
2015-03-29 14:09:48 +00:00
|
|
|
w.flushHeaders()
|
2015-03-28 22:07:40 +00:00
|
|
|
return w.Writer.Write(b)
|
|
|
|
}
|
2015-03-29 14:09:48 +00:00
|
|
|
|
|
|
|
func (w *ResponseWriter) flushHeaders() {
|
|
|
|
if w.headersDone {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
w.rw.WriteHeader(w.statusCode)
|
|
|
|
w.headersDone = true
|
|
|
|
}
|
|
|
|
|
|
|
|
func (w *ResponseWriter) setChunked() {
|
|
|
|
w.Header().Del("Content-Length")
|
|
|
|
}
|