mirror of
https://github.com/ipfs/kubo.git
synced 2025-06-28 17:03:58 +08:00
cmds/http/handler: set stream error trailer
stream output might break. in these cases we need to notify the client. this is after a 200 response has been sent. We do this by setting a special trailer (header after the body): X-Stream-Error: <error cause> This is similar to what's done by systems like gRPC. This still needs to be read + handled on the other side. License: MIT Signed-off-by: Juan Batiz-Benet <juan@benet.ai>
This commit is contained in:
@ -32,6 +32,7 @@ type Handler struct {
|
||||
var ErrNotFound = errors.New("404 page not found")
|
||||
|
||||
const (
|
||||
StreamErrHeader = "X-Stream-Error"
|
||||
streamHeader = "X-Stream-Output"
|
||||
channelHeader = "X-Chunked-Output"
|
||||
contentTypeHeader = "Content-Type"
|
||||
@ -213,8 +214,8 @@ func copyChunks(contentType string, w http.ResponseWriter, out io.Reader) error
|
||||
writer.WriteString(transferEncodingHeader + ": chunked\r\n")
|
||||
writer.WriteString(channelHeader + ": 1\r\n\r\n")
|
||||
|
||||
writeChunks := func() error {
|
||||
buf := make([]byte, 32*1024)
|
||||
|
||||
for {
|
||||
n, err := out.Read(buf)
|
||||
|
||||
@ -238,11 +239,27 @@ func copyChunks(contentType string, w http.ResponseWriter, out io.Reader) error
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
writer.WriteString("0\r\n\r\n")
|
||||
writer.Flush()
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
streamErr := writeChunks()
|
||||
writer.WriteString("0\r\n") // close body
|
||||
|
||||
// if there was a stream error, write out an error trailer. hopefully
|
||||
// the client will pick it up!
|
||||
if streamErr != nil {
|
||||
writer.WriteString(StreamErrHeader + ": " + sanitizedErrStr(err) + "\r\n")
|
||||
}
|
||||
writer.WriteString("\r\n") // close response
|
||||
writer.Flush()
|
||||
return nil
|
||||
}
|
||||
|
||||
func sanitizedErrStr(err error) string {
|
||||
s := err.Error()
|
||||
s = strings.Split(s, "\n")[0]
|
||||
s = strings.Split(s, "\r")[0]
|
||||
return s
|
||||
}
|
||||
|
||||
type flushResponse struct {
|
||||
|
Reference in New Issue
Block a user