<commit_before>// +build js

package http

import (
	"bufio"
	"bytes"
	"errors"
	"io/ioutil"
	"net/textproto"

	"github.com/gopherjs/gopherjs/js"
)

var DefaultTransport RoundTripper = &XhrTransport{
	inflight: map[*Request]*js.Object{},
}

type XhrTransport struct {
	inflight map[*Request]*js.Object
}

func (t *XhrTransport) RoundTrip(req *Request) (*Response, error) {
	xhrConstructor := js.Global.Get("XMLHttpRequest")
	if xhrConstructor == js.Undefined {
		return nil, errors.New("net/http: XMLHttpRequest not available")
	}
	xhr := xhrConstructor.New()
	xhr.Set("responseType", "arraybuffer")
	t.inflight[req] = xhr
	defer delete(t.inflight, req)

	respCh := make(chan *Response)
	errCh := make(chan error)

	xhr.Set("onload", func() {
		header, _ := textproto.NewReader(bufio.NewReader(bytes.NewReader([]byte(xhr.Call("getAllResponseHeaders").String() + "\n")))).ReadMIMEHeader()
		body := js.Global.Get("Uint8Array").New(xhr.Get("response")).Interface().([]byte)
		respCh <- &Response{
			Status:        xhr.Get("status").String() + " " + xhr.Get("statusText").String(),
			StatusCode:    xhr.Get("status").Int(),
			Header:        Header(header),
			ContentLength: int64(len(body)),
			Body:          ioutil.NopCloser(bytes.NewReader(body)),
			Request:       req,
		}
	})

	xhr.Set("onerror", func(e *js.Object) {
		errCh <- errors.New("net/http: XMLHttpRequest failed")
	})

	xhr.Set("onabort", func(e *js.Object) {
		errCh <- errors.New("net/http: request canceled")
	})

	xhr.Call("open", req.Method, req.URL.String())
	for key, values := range req.Header {
		for _, value := range values {
			xhr.Call("setRequestHeader", key, value)
		}
	}
	var body []byte
	if req.Body != nil {
		var err error
		body, err = ioutil.ReadAll(req.Body)
		if err != nil {
			return nil, err
		}
	}
	xhr.Call("send", body)

	select {
	case resp := <-respCh:
		return resp, nil
	case err := <-errCh:
		return nil, err
	}
}

func (t *XhrTransport) CancelRequest(req *Request) {
	t.inflight[req].Call("abort")
}<commit_msg>renamed and improved http.XHRTransport<commit_after>// +build js

package http

import (
	"bufio"
	"bytes"
	"errors"
	"io/ioutil"
	"net/textproto"

	"github.com/gopherjs/gopherjs/js"
)

var DefaultTransport RoundTripper = &XHRTransport{}

type XHRTransport struct {
	inflight map[*Request]*js.Object
}

func (t *XHRTransport) RoundTrip(req *Request) (*Response, error) {
	xhrConstructor := js.Global.Get("XMLHttpRequest")
	if xhrConstructor == js.Undefined {
		return nil, errors.New("net/http: XMLHttpRequest not available")
	}
	xhr := xhrConstructor.New()
	xhr.Set("responseType", "arraybuffer")

	if t.inflight == nil {
		t.inflight = map[*Request]*js.Object{}
	}
	t.inflight[req] = xhr
	defer delete(t.inflight, req)

	respCh := make(chan *Response)
	errCh := make(chan error)

	xhr.Set("onload", func() {
		header, _ := textproto.NewReader(bufio.NewReader(bytes.NewReader([]byte(xhr.Call("getAllResponseHeaders").String() + "\n")))).ReadMIMEHeader()
		body := js.Global.Get("Uint8Array").New(xhr.Get("response")).Interface().([]byte)
		respCh <- &Response{
			Status:        xhr.Get("status").String() + " " + xhr.Get("statusText").String(),
			StatusCode:    xhr.Get("status").Int(),
			Header:        Header(header),
			ContentLength: int64(len(body)),
			Body:          ioutil.NopCloser(bytes.NewReader(body)),
			Request:       req,
		}
	})

	xhr.Set("onerror", func(e *js.Object) {
		errCh <- errors.New("net/http: XMLHttpRequest failed")
	})

	xhr.Set("onabort", func(e *js.Object) {
		errCh <- errors.New("net/http: request canceled")
	})

	xhr.Call("open", req.Method, req.URL.String())
	for key, values := range req.Header {
		for _, value := range values {
			xhr.Call("setRequestHeader", key, value)
		}
	}
	var body []byte
	if req.Body != nil {
		var err error
		body, err = ioutil.ReadAll(req.Body)
		if err != nil {
			return nil, err
		}
	}
	xhr.Call("send", body)

	select {
	case resp := <-respCh:
		return resp, nil
	case err := <-errCh:
		return nil, err
	}
}

func (t *XHRTransport) CancelRequest(req *Request) {
	if xhr, ok := t.inflight[req]; ok {
		xhr.Call("abort")
	}
}
{'fraction_non_alphanumeric': 0.17647058823529413, 'fraction_numerical': 0.0014584346135148275, 'mean_word_length': 3.9818401937046004, 'pattern_counts': {'":': 0, '<': 13, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2249047', 'n_tokens_mistral': 1615, 'n_tokens_neox': 1520, 'n_words': 303}