OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-dev/] [or1k-gcc/] [libgo/] [go/] [net/] [http/] [transport_test.go] - Rev 747

Compare with Previous | Blame | View Log

// Copyright 2011 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// Tests for transport.go

package http_test

import (
        "bytes"
        "compress/gzip"
        "crypto/rand"
        "fmt"
        "io"
        "io/ioutil"
        . "net/http"
        "net/http/httptest"
        "net/url"
        "strconv"
        "strings"
        "testing"
        "time"
)

// TODO: test 5 pipelined requests with responses: 1) OK, 2) OK, Connection: Close
//       and then verify that the final 2 responses get errors back.

// hostPortHandler writes back the client's "host:port".
var hostPortHandler = HandlerFunc(func(w ResponseWriter, r *Request) {
        if r.FormValue("close") == "true" {
                w.Header().Set("Connection", "close")
        }
        w.Write([]byte(r.RemoteAddr))
})

// Two subsequent requests and verify their response is the same.
// The response from the server is our own IP:port
func TestTransportKeepAlives(t *testing.T) {
        ts := httptest.NewServer(hostPortHandler)
        defer ts.Close()

        for _, disableKeepAlive := range []bool{false, true} {
                tr := &Transport{DisableKeepAlives: disableKeepAlive}
                c := &Client{Transport: tr}

                fetch := func(n int) string {
                        res, err := c.Get(ts.URL)
                        if err != nil {
                                t.Fatalf("error in disableKeepAlive=%v, req #%d, GET: %v", disableKeepAlive, n, err)
                        }
                        body, err := ioutil.ReadAll(res.Body)
                        if err != nil {
                                t.Fatalf("error in disableKeepAlive=%v, req #%d, ReadAll: %v", disableKeepAlive, n, err)
                        }
                        return string(body)
                }

                body1 := fetch(1)
                body2 := fetch(2)

                bodiesDiffer := body1 != body2
                if bodiesDiffer != disableKeepAlive {
                        t.Errorf("error in disableKeepAlive=%v. unexpected bodiesDiffer=%v; body1=%q; body2=%q",
                                disableKeepAlive, bodiesDiffer, body1, body2)
                }
        }
}

func TestTransportConnectionCloseOnResponse(t *testing.T) {
        ts := httptest.NewServer(hostPortHandler)
        defer ts.Close()

        for _, connectionClose := range []bool{false, true} {
                tr := &Transport{}
                c := &Client{Transport: tr}

                fetch := func(n int) string {
                        req := new(Request)
                        var err error
                        req.URL, err = url.Parse(ts.URL + fmt.Sprintf("/?close=%v", connectionClose))
                        if err != nil {
                                t.Fatalf("URL parse error: %v", err)
                        }
                        req.Method = "GET"
                        req.Proto = "HTTP/1.1"
                        req.ProtoMajor = 1
                        req.ProtoMinor = 1

                        res, err := c.Do(req)
                        if err != nil {
                                t.Fatalf("error in connectionClose=%v, req #%d, Do: %v", connectionClose, n, err)
                        }
                        body, err := ioutil.ReadAll(res.Body)
                        defer res.Body.Close()
                        if err != nil {
                                t.Fatalf("error in connectionClose=%v, req #%d, ReadAll: %v", connectionClose, n, err)
                        }
                        return string(body)
                }

                body1 := fetch(1)
                body2 := fetch(2)
                bodiesDiffer := body1 != body2
                if bodiesDiffer != connectionClose {
                        t.Errorf("error in connectionClose=%v. unexpected bodiesDiffer=%v; body1=%q; body2=%q",
                                connectionClose, bodiesDiffer, body1, body2)
                }
        }
}

func TestTransportConnectionCloseOnRequest(t *testing.T) {
        ts := httptest.NewServer(hostPortHandler)
        defer ts.Close()

        for _, connectionClose := range []bool{false, true} {
                tr := &Transport{}
                c := &Client{Transport: tr}

                fetch := func(n int) string {
                        req := new(Request)
                        var err error
                        req.URL, err = url.Parse(ts.URL)
                        if err != nil {
                                t.Fatalf("URL parse error: %v", err)
                        }
                        req.Method = "GET"
                        req.Proto = "HTTP/1.1"
                        req.ProtoMajor = 1
                        req.ProtoMinor = 1
                        req.Close = connectionClose

                        res, err := c.Do(req)
                        if err != nil {
                                t.Fatalf("error in connectionClose=%v, req #%d, Do: %v", connectionClose, n, err)
                        }
                        body, err := ioutil.ReadAll(res.Body)
                        if err != nil {
                                t.Fatalf("error in connectionClose=%v, req #%d, ReadAll: %v", connectionClose, n, err)
                        }
                        return string(body)
                }

                body1 := fetch(1)
                body2 := fetch(2)
                bodiesDiffer := body1 != body2
                if bodiesDiffer != connectionClose {
                        t.Errorf("error in connectionClose=%v. unexpected bodiesDiffer=%v; body1=%q; body2=%q",
                                connectionClose, bodiesDiffer, body1, body2)
                }
        }
}

func TestTransportIdleCacheKeys(t *testing.T) {
        ts := httptest.NewServer(hostPortHandler)
        defer ts.Close()

        tr := &Transport{DisableKeepAlives: false}
        c := &Client{Transport: tr}

        if e, g := 0, len(tr.IdleConnKeysForTesting()); e != g {
                t.Errorf("After CloseIdleConnections expected %d idle conn cache keys; got %d", e, g)
        }

        resp, err := c.Get(ts.URL)
        if err != nil {
                t.Error(err)
        }
        ioutil.ReadAll(resp.Body)

        keys := tr.IdleConnKeysForTesting()
        if e, g := 1, len(keys); e != g {
                t.Fatalf("After Get expected %d idle conn cache keys; got %d", e, g)
        }

        if e := "|http|" + ts.Listener.Addr().String(); keys[0] != e {
                t.Errorf("Expected idle cache key %q; got %q", e, keys[0])
        }

        tr.CloseIdleConnections()
        if e, g := 0, len(tr.IdleConnKeysForTesting()); e != g {
                t.Errorf("After CloseIdleConnections expected %d idle conn cache keys; got %d", e, g)
        }
}

func TestTransportMaxPerHostIdleConns(t *testing.T) {
        resch := make(chan string)
        gotReq := make(chan bool)
        ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
                gotReq <- true
                msg := <-resch
                _, err := w.Write([]byte(msg))
                if err != nil {
                        t.Fatalf("Write: %v", err)
                }
        }))
        defer ts.Close()
        maxIdleConns := 2
        tr := &Transport{DisableKeepAlives: false, MaxIdleConnsPerHost: maxIdleConns}
        c := &Client{Transport: tr}

        // Start 3 outstanding requests and wait for the server to get them.
        // Their responses will hang until we we write to resch, though.
        donech := make(chan bool)
        doReq := func() {
                resp, err := c.Get(ts.URL)
                if err != nil {
                        t.Error(err)
                }
                _, err = ioutil.ReadAll(resp.Body)
                if err != nil {
                        t.Fatalf("ReadAll: %v", err)
                }
                donech <- true
        }
        go doReq()
        <-gotReq
        go doReq()
        <-gotReq
        go doReq()
        <-gotReq

        if e, g := 0, len(tr.IdleConnKeysForTesting()); e != g {
                t.Fatalf("Before writes, expected %d idle conn cache keys; got %d", e, g)
        }

        resch <- "res1"
        <-donech
        keys := tr.IdleConnKeysForTesting()
        if e, g := 1, len(keys); e != g {
                t.Fatalf("after first response, expected %d idle conn cache keys; got %d", e, g)
        }
        cacheKey := "|http|" + ts.Listener.Addr().String()
        if keys[0] != cacheKey {
                t.Fatalf("Expected idle cache key %q; got %q", cacheKey, keys[0])
        }
        if e, g := 1, tr.IdleConnCountForTesting(cacheKey); e != g {
                t.Errorf("after first response, expected %d idle conns; got %d", e, g)
        }

        resch <- "res2"
        <-donech
        if e, g := 2, tr.IdleConnCountForTesting(cacheKey); e != g {
                t.Errorf("after second response, expected %d idle conns; got %d", e, g)
        }

        resch <- "res3"
        <-donech
        if e, g := maxIdleConns, tr.IdleConnCountForTesting(cacheKey); e != g {
                t.Errorf("after third response, still expected %d idle conns; got %d", e, g)
        }
}

func TestTransportServerClosingUnexpectedly(t *testing.T) {
        ts := httptest.NewServer(hostPortHandler)
        defer ts.Close()

        tr := &Transport{}
        c := &Client{Transport: tr}

        fetch := func(n, retries int) string {
                condFatalf := func(format string, arg ...interface{}) {
                        if retries <= 0 {
                                t.Fatalf(format, arg...)
                        }
                        t.Logf("retrying shortly after expected error: "+format, arg...)
                        time.Sleep(time.Second / time.Duration(retries))
                }
                for retries >= 0 {
                        retries--
                        res, err := c.Get(ts.URL)
                        if err != nil {
                                condFatalf("error in req #%d, GET: %v", n, err)
                                continue
                        }
                        body, err := ioutil.ReadAll(res.Body)
                        if err != nil {
                                condFatalf("error in req #%d, ReadAll: %v", n, err)
                                continue
                        }
                        res.Body.Close()
                        return string(body)
                }
                panic("unreachable")
        }

        body1 := fetch(1, 0)
        body2 := fetch(2, 0)

        ts.CloseClientConnections() // surprise!

        // This test has an expected race. Sleeping for 25 ms prevents
        // it on most fast machines, causing the next fetch() call to
        // succeed quickly.  But if we do get errors, fetch() will retry 5
        // times with some delays between.
        time.Sleep(25 * time.Millisecond)

        body3 := fetch(3, 5)

        if body1 != body2 {
                t.Errorf("expected body1 and body2 to be equal")
        }
        if body2 == body3 {
                t.Errorf("expected body2 and body3 to be different")
        }
}

// Test for http://golang.org/issue/2616 (appropriate issue number)
// This fails pretty reliably with GOMAXPROCS=100 or something high.
func TestStressSurpriseServerCloses(t *testing.T) {
        if testing.Short() {
                t.Logf("skipping test in short mode")
                return
        }
        ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
                w.Header().Set("Content-Length", "5")
                w.Header().Set("Content-Type", "text/plain")
                w.Write([]byte("Hello"))
                w.(Flusher).Flush()
                conn, buf, _ := w.(Hijacker).Hijack()
                buf.Flush()
                conn.Close()
        }))
        defer ts.Close()

        tr := &Transport{DisableKeepAlives: false}
        c := &Client{Transport: tr}

        // Do a bunch of traffic from different goroutines. Send to activityc
        // after each request completes, regardless of whether it failed.
        const (
                numClients    = 50
                reqsPerClient = 250
        )
        activityc := make(chan bool)
        for i := 0; i < numClients; i++ {
                go func() {
                        for i := 0; i < reqsPerClient; i++ {
                                res, err := c.Get(ts.URL)
                                if err == nil {
                                        // We expect errors since the server is
                                        // hanging up on us after telling us to
                                        // send more requests, so we don't
                                        // actually care what the error is.
                                        // But we want to close the body in cases
                                        // where we won the race.
                                        res.Body.Close()
                                }
                                activityc <- true
                        }
                }()
        }

        // Make sure all the request come back, one way or another.
        for i := 0; i < numClients*reqsPerClient; i++ {
                select {
                case <-activityc:
                case <-time.After(5 * time.Second):
                        t.Fatalf("presumed deadlock; no HTTP client activity seen in awhile")
                }
        }
}

// TestTransportHeadResponses verifies that we deal with Content-Lengths
// with no bodies properly
func TestTransportHeadResponses(t *testing.T) {
        ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
                if r.Method != "HEAD" {
                        panic("expected HEAD; got " + r.Method)
                }
                w.Header().Set("Content-Length", "123")
                w.WriteHeader(200)
        }))
        defer ts.Close()

        tr := &Transport{DisableKeepAlives: false}
        c := &Client{Transport: tr}
        for i := 0; i < 2; i++ {
                res, err := c.Head(ts.URL)
                if err != nil {
                        t.Errorf("error on loop %d: %v", i, err)
                }
                if e, g := "123", res.Header.Get("Content-Length"); e != g {
                        t.Errorf("loop %d: expected Content-Length header of %q, got %q", i, e, g)
                }
                if e, g := int64(0), res.ContentLength; e != g {
                        t.Errorf("loop %d: expected res.ContentLength of %v, got %v", i, e, g)
                }
        }
}

// TestTransportHeadChunkedResponse verifies that we ignore chunked transfer-encoding
// on responses to HEAD requests.
func TestTransportHeadChunkedResponse(t *testing.T) {
        ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
                if r.Method != "HEAD" {
                        panic("expected HEAD; got " + r.Method)
                }
                w.Header().Set("Transfer-Encoding", "chunked") // client should ignore
                w.Header().Set("x-client-ipport", r.RemoteAddr)
                w.WriteHeader(200)
        }))
        defer ts.Close()

        tr := &Transport{DisableKeepAlives: false}
        c := &Client{Transport: tr}

        res1, err := c.Head(ts.URL)
        if err != nil {
                t.Fatalf("request 1 error: %v", err)
        }
        res2, err := c.Head(ts.URL)
        if err != nil {
                t.Fatalf("request 2 error: %v", err)
        }
        if v1, v2 := res1.Header.Get("x-client-ipport"), res2.Header.Get("x-client-ipport"); v1 != v2 {
                t.Errorf("ip/ports differed between head requests: %q vs %q", v1, v2)
        }
}

var roundTripTests = []struct {
        accept       string
        expectAccept string
        compressed   bool
}{
        // Requests with no accept-encoding header use transparent compression
        {"", "gzip", false},
        // Requests with other accept-encoding should pass through unmodified
        {"foo", "foo", false},
        // Requests with accept-encoding == gzip should be passed through
        {"gzip", "gzip", true},
}

// Test that the modification made to the Request by the RoundTripper is cleaned up
func TestRoundTripGzip(t *testing.T) {
        const responseBody = "test response body"
        ts := httptest.NewServer(HandlerFunc(func(rw ResponseWriter, req *Request) {
                accept := req.Header.Get("Accept-Encoding")
                if expect := req.FormValue("expect_accept"); accept != expect {
                        t.Errorf("in handler, test %v: Accept-Encoding = %q, want %q",
                                req.FormValue("testnum"), accept, expect)
                }
                if accept == "gzip" {
                        rw.Header().Set("Content-Encoding", "gzip")
                        gz, err := gzip.NewWriter(rw)
                        if err != nil {
                                t.Errorf("gzip NewWriter: %v", err)
                                return
                        }
                        gz.Write([]byte(responseBody))
                        gz.Close()
                } else {
                        rw.Header().Set("Content-Encoding", accept)
                        rw.Write([]byte(responseBody))
                }
        }))
        defer ts.Close()

        for i, test := range roundTripTests {
                // Test basic request (no accept-encoding)
                req, _ := NewRequest("GET", fmt.Sprintf("%s/?testnum=%d&expect_accept=%s", ts.URL, i, test.expectAccept), nil)
                if test.accept != "" {
                        req.Header.Set("Accept-Encoding", test.accept)
                }
                res, err := DefaultTransport.RoundTrip(req)
                var body []byte
                if test.compressed {
                        gzip, err := gzip.NewReader(res.Body)
                        if err != nil {
                                t.Errorf("%d. gzip NewReader: %v", i, err)
                                continue
                        }
                        body, err = ioutil.ReadAll(gzip)
                        res.Body.Close()
                } else {
                        body, err = ioutil.ReadAll(res.Body)
                }
                if err != nil {
                        t.Errorf("%d. Error: %q", i, err)
                        continue
                }
                if g, e := string(body), responseBody; g != e {
                        t.Errorf("%d. body = %q; want %q", i, g, e)
                }
                if g, e := req.Header.Get("Accept-Encoding"), test.accept; g != e {
                        t.Errorf("%d. Accept-Encoding = %q; want %q (it was mutated, in violation of RoundTrip contract)", i, g, e)
                }
                if g, e := res.Header.Get("Content-Encoding"), test.accept; g != e {
                        t.Errorf("%d. Content-Encoding = %q; want %q", i, g, e)
                }
        }

}

func TestTransportGzip(t *testing.T) {
        const testString = "The test string aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
        const nRandBytes = 1024 * 1024
        ts := httptest.NewServer(HandlerFunc(func(rw ResponseWriter, req *Request) {
                if g, e := req.Header.Get("Accept-Encoding"), "gzip"; g != e {
                        t.Errorf("Accept-Encoding = %q, want %q", g, e)
                }
                rw.Header().Set("Content-Encoding", "gzip")
                if req.Method == "HEAD" {
                        return
                }

                var w io.Writer = rw
                var buf bytes.Buffer
                if req.FormValue("chunked") == "0" {
                        w = &buf
                        defer io.Copy(rw, &buf)
                        defer func() {
                                rw.Header().Set("Content-Length", strconv.Itoa(buf.Len()))
                        }()
                }
                gz, _ := gzip.NewWriter(w)
                gz.Write([]byte(testString))
                if req.FormValue("body") == "large" {
                        io.CopyN(gz, rand.Reader, nRandBytes)
                }
                gz.Close()
        }))
        defer ts.Close()

        for _, chunked := range []string{"1", "0"} {
                c := &Client{Transport: &Transport{}}

                // First fetch something large, but only read some of it.
                res, err := c.Get(ts.URL + "/?body=large&chunked=" + chunked)
                if err != nil {
                        t.Fatalf("large get: %v", err)
                }
                buf := make([]byte, len(testString))
                n, err := io.ReadFull(res.Body, buf)
                if err != nil {
                        t.Fatalf("partial read of large response: size=%d, %v", n, err)
                }
                if e, g := testString, string(buf); e != g {
                        t.Errorf("partial read got %q, expected %q", g, e)
                }
                res.Body.Close()
                // Read on the body, even though it's closed
                n, err = res.Body.Read(buf)
                if n != 0 || err == nil {
                        t.Errorf("expected error post-closed large Read; got = %d, %v", n, err)
                }

                // Then something small.
                res, err = c.Get(ts.URL + "/?chunked=" + chunked)
                if err != nil {
                        t.Fatal(err)
                }
                body, err := ioutil.ReadAll(res.Body)
                if err != nil {
                        t.Fatal(err)
                }
                if g, e := string(body), testString; g != e {
                        t.Fatalf("body = %q; want %q", g, e)
                }
                if g, e := res.Header.Get("Content-Encoding"), ""; g != e {
                        t.Fatalf("Content-Encoding = %q; want %q", g, e)
                }

                // Read on the body after it's been fully read:
                n, err = res.Body.Read(buf)
                if n != 0 || err == nil {
                        t.Errorf("expected Read error after exhausted reads; got %d, %v", n, err)
                }
                res.Body.Close()
                n, err = res.Body.Read(buf)
                if n != 0 || err == nil {
                        t.Errorf("expected Read error after Close; got %d, %v", n, err)
                }
        }

        // And a HEAD request too, because they're always weird.
        c := &Client{Transport: &Transport{}}
        res, err := c.Head(ts.URL)
        if err != nil {
                t.Fatalf("Head: %v", err)
        }
        if res.StatusCode != 200 {
                t.Errorf("Head status=%d; want=200", res.StatusCode)
        }
}

func TestTransportProxy(t *testing.T) {
        ch := make(chan string, 1)
        ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
                ch <- "real server"
        }))
        defer ts.Close()
        proxy := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
                ch <- "proxy for " + r.URL.String()
        }))
        defer proxy.Close()

        pu, err := url.Parse(proxy.URL)
        if err != nil {
                t.Fatal(err)
        }
        c := &Client{Transport: &Transport{Proxy: ProxyURL(pu)}}
        c.Head(ts.URL)
        got := <-ch
        want := "proxy for " + ts.URL + "/"
        if got != want {
                t.Errorf("want %q, got %q", want, got)
        }
}

// TestTransportGzipRecursive sends a gzip quine and checks that the
// client gets the same value back. This is more cute than anything,
// but checks that we don't recurse forever, and checks that
// Content-Encoding is removed.
func TestTransportGzipRecursive(t *testing.T) {
        ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
                w.Header().Set("Content-Encoding", "gzip")
                w.Write(rgz)
        }))
        defer ts.Close()

        c := &Client{Transport: &Transport{}}
        res, err := c.Get(ts.URL)
        if err != nil {
                t.Fatal(err)
        }
        body, err := ioutil.ReadAll(res.Body)
        if err != nil {
                t.Fatal(err)
        }
        if !bytes.Equal(body, rgz) {
                t.Fatalf("Incorrect result from recursive gz:\nhave=%x\nwant=%x",
                        body, rgz)
        }
        if g, e := res.Header.Get("Content-Encoding"), ""; g != e {
                t.Fatalf("Content-Encoding = %q; want %q", g, e)
        }
}

type fooProto struct{}

func (fooProto) RoundTrip(req *Request) (*Response, error) {
        res := &Response{
                Status:     "200 OK",
                StatusCode: 200,
                Header:     make(Header),
                Body:       ioutil.NopCloser(strings.NewReader("You wanted " + req.URL.String())),
        }
        return res, nil
}

func TestTransportAltProto(t *testing.T) {
        tr := &Transport{}
        c := &Client{Transport: tr}
        tr.RegisterProtocol("foo", fooProto{})
        res, err := c.Get("foo://bar.com/path")
        if err != nil {
                t.Fatal(err)
        }
        bodyb, err := ioutil.ReadAll(res.Body)
        if err != nil {
                t.Fatal(err)
        }
        body := string(bodyb)
        if e := "You wanted foo://bar.com/path"; body != e {
                t.Errorf("got response %q, want %q", body, e)
        }
}

// rgz is a gzip quine that uncompresses to itself.
var rgz = []byte{
        0x1f, 0x8b, 0x08, 0x08, 0x00, 0x00, 0x00, 0x00,
        0x00, 0x00, 0x72, 0x65, 0x63, 0x75, 0x72, 0x73,
        0x69, 0x76, 0x65, 0x00, 0x92, 0xef, 0xe6, 0xe0,
        0x60, 0x00, 0x83, 0xa2, 0xd4, 0xe4, 0xd2, 0xa2,
        0xe2, 0xcc, 0xb2, 0x54, 0x06, 0x00, 0x00, 0x17,
        0x00, 0xe8, 0xff, 0x92, 0xef, 0xe6, 0xe0, 0x60,
        0x00, 0x83, 0xa2, 0xd4, 0xe4, 0xd2, 0xa2, 0xe2,
        0xcc, 0xb2, 0x54, 0x06, 0x00, 0x00, 0x17, 0x00,
        0xe8, 0xff, 0x42, 0x12, 0x46, 0x16, 0x06, 0x00,
        0x05, 0x00, 0xfa, 0xff, 0x42, 0x12, 0x46, 0x16,
        0x06, 0x00, 0x05, 0x00, 0xfa, 0xff, 0x00, 0x05,
        0x00, 0xfa, 0xff, 0x00, 0x14, 0x00, 0xeb, 0xff,
        0x42, 0x12, 0x46, 0x16, 0x06, 0x00, 0x05, 0x00,
        0xfa, 0xff, 0x00, 0x05, 0x00, 0xfa, 0xff, 0x00,
        0x14, 0x00, 0xeb, 0xff, 0x42, 0x88, 0x21, 0xc4,
        0x00, 0x00, 0x14, 0x00, 0xeb, 0xff, 0x42, 0x88,
        0x21, 0xc4, 0x00, 0x00, 0x14, 0x00, 0xeb, 0xff,
        0x42, 0x88, 0x21, 0xc4, 0x00, 0x00, 0x14, 0x00,
        0xeb, 0xff, 0x42, 0x88, 0x21, 0xc4, 0x00, 0x00,
        0x14, 0x00, 0xeb, 0xff, 0x42, 0x88, 0x21, 0xc4,
        0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00,
        0x00, 0xff, 0xff, 0x00, 0x17, 0x00, 0xe8, 0xff,
        0x42, 0x88, 0x21, 0xc4, 0x00, 0x00, 0x00, 0x00,
        0xff, 0xff, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00,
        0x17, 0x00, 0xe8, 0xff, 0x42, 0x12, 0x46, 0x16,
        0x06, 0x00, 0x00, 0x00, 0xff, 0xff, 0x01, 0x08,
        0x00, 0xf7, 0xff, 0x3d, 0xb1, 0x20, 0x85, 0xfa,
        0x00, 0x00, 0x00, 0x42, 0x12, 0x46, 0x16, 0x06,
        0x00, 0x00, 0x00, 0xff, 0xff, 0x01, 0x08, 0x00,
        0xf7, 0xff, 0x3d, 0xb1, 0x20, 0x85, 0xfa, 0x00,
        0x00, 0x00, 0x3d, 0xb1, 0x20, 0x85, 0xfa, 0x00,
        0x00, 0x00,
}

Compare with Previous | Blame | View Log

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.