github.com/AlpineAIO/wails/v2@v2.0.0-beta.32.0.20240505041856-1047a8fa5fef/pkg/assetserver/webview/responsewriter_windows.go (about)

     1  //go:build windows
     2  // +build windows
     3  
     4  package webview
     5  
     6  import (
     7  	"bytes"
     8  	"fmt"
     9  	"net/http"
    10  	"strings"
    11  )
    12  
    13  var _ http.ResponseWriter = &responseWriter{}
    14  
    15  type responseWriter struct {
    16  	req *request
    17  
    18  	header      http.Header
    19  	wroteHeader bool
    20  	code        int
    21  	body        *bytes.Buffer
    22  
    23  	finished bool
    24  }
    25  
    26  func (rw *responseWriter) Header() http.Header {
    27  	if rw.header == nil {
    28  		rw.header = http.Header{}
    29  	}
    30  	return rw.header
    31  }
    32  
    33  func (rw *responseWriter) Write(buf []byte) (int, error) {
    34  	if rw.finished {
    35  		return 0, errResponseFinished
    36  	}
    37  
    38  	rw.WriteHeader(http.StatusOK)
    39  
    40  	return rw.body.Write(buf)
    41  }
    42  
    43  func (rw *responseWriter) WriteHeader(code int) {
    44  	if rw.wroteHeader || rw.finished {
    45  		return
    46  	}
    47  	rw.wroteHeader = true
    48  
    49  	if rw.body == nil {
    50  		rw.body = &bytes.Buffer{}
    51  	}
    52  
    53  	rw.code = code
    54  }
    55  
    56  func (rw *responseWriter) Finish() error {
    57  	if !rw.wroteHeader {
    58  		rw.WriteHeader(http.StatusNotImplemented)
    59  	}
    60  
    61  	if rw.finished {
    62  		return nil
    63  	}
    64  	rw.finished = true
    65  
    66  	var errs []error
    67  
    68  	code := rw.code
    69  	if code == http.StatusNotModified {
    70  		// WebView2 has problems when a request returns a 304 status code and the WebView2 is going to hang for other
    71  		// requests including IPC calls.
    72  		errs = append(errs, fmt.Errorf("AssetServer returned 304 - StatusNotModified which are going to hang WebView2, changed code to 505 - StatusInternalServerError"))
    73  		code = http.StatusInternalServerError
    74  	}
    75  
    76  	rw.req.invokeSync(func() {
    77  		resp := rw.req.response
    78  
    79  		hdrs, err := resp.GetHeaders()
    80  		if err != nil {
    81  			errs = append(errs, fmt.Errorf("Resp.GetHeaders failed: %s", err))
    82  		} else {
    83  			for k, v := range rw.header {
    84  				if err := hdrs.AppendHeader(k, strings.Join(v, ",")); err != nil {
    85  					errs = append(errs, fmt.Errorf("Resp.AppendHeader failed: %s", err))
    86  				}
    87  			}
    88  			hdrs.Release()
    89  		}
    90  
    91  		if err := resp.PutStatusCode(code); err != nil {
    92  			errs = append(errs, fmt.Errorf("Resp.PutStatusCode failed: %s", err))
    93  		}
    94  
    95  		if err := resp.PutByteContent(rw.body.Bytes()); err != nil {
    96  			errs = append(errs, fmt.Errorf("Resp.PutByteContent failed: %s", err))
    97  		}
    98  
    99  		if err := rw.req.finishResponse(); err != nil {
   100  			errs = append(errs, fmt.Errorf("Resp.finishResponse failed: %s", err))
   101  		}
   102  	})
   103  
   104  	return combineErrs(errs)
   105  }