GithubHelp home page GithubHelp logo

deislabs / wasi-experimental-http Goto Github PK

View Code? Open in Web Editor NEW
134.0 17.0 34.0 239 KB

Experimental outbound HTTP support for WebAssembly and WASI

License: MIT License

Rust 79.32% TypeScript 20.68%
webassembly wasi wasmtime

wasi-experimental-http's Introduction

wasi-experimental-http

This is an experiment intended to provide a temporary workaround until the WASI networking API is stable, and is compatible with Wasmtime v0.26 by using the wasi_experiemental_http_wasmtime crate. We expect that once the WASI sockets proposal gets adopted and implemented in language toolchains, the need for this library will vanish.

Writing a module that makes an HTTP request

We use the wasi-experimental-http crate (from this repository) and the http crate to create an HTTP request from a WebAssembly module, make a host call to the runtime using the request, then get a response back:

use bytes::Bytes;
use http;
use wasi_experimental_http;

#[no_mangle]
pub extern "C" fn _start() {
    let url = "https://postman-echo.com/post".to_string();
    let req = http::request::Builder::new()
        .method(http::Method::POST)
        .uri(&url)
        .header("Content-Type", "text/plain")
        .header("abc", "def");
    let b = Bytes::from("Testing with a request body. Does this actually work?");
    let req = req.body(Some(b)).unwrap();

    let res = wasi_experimental_http::request(req).expect("cannot make request");
    let str = std::str::from_utf8(&res.body_read_all()).unwrap().to_string();
    println!("{:#?}", res.header_get("Content-Type"));
    println!("{}", str);
    println!("{:#?}", res.status_code);
}

Build the module using the wasm32-wasi target, then follow the next section to update a Wasmtime runtime with the experimental HTTP support.

Adding support to a Wasmtime runtime

The easiest way to add support is by using the Wasmtime linker:

let store = Store::default();
let mut linker = Linker::new(&store);
let wasi = Wasi::new(&store, ctx);

// link the WASI core functions
wasi.add_to_linker(&mut linker)?;

// link the experimental HTTP support
let allowed_hosts = Some(vec!["https://postman-echo.com".to_string()]);
let max_concurrent_requests = Some(42);

let http = HttpCtx::new(allowed_domains, max_concurrent_requests)?;
http.add_to_linker(&mut linker)?;

Then, executing the module above will send the HTTP request and write the response:

{
    "content-length": "374",
    "connection": "keep-alive",
    "set-cookie": "sails.Path=/; HttpOnly",
    "vary": "Accept-Encoding",
    "content-type": "application/json; charset=utf-8",
    "date": "Fri, 26 Feb 2021 18:31:03 GMT",
    "etag": "W/\"176-Ky4OTmr3Xbcl3yNah8w2XIQapGU\"",
}
{"args":{},"data":"Testing with a request body. Does this actually work?","files":{},"form":{},"headers":{"x-forwarded-proto":"https","x-forwarded-port":"443","host":"postman-echo.com","x-amzn-trace-id":"Root=1-60393e67-02d1c8033bcf4f1e74a4523e","content-length":"53","content-type":"text/plain","abc":"def","accept":"*/*"},"json":null,"url":"https://postman-echo.com/post"}
"200 OK"

The Wasmtime implementation also enables allowed hosts - an optional and configurable list of domains or hosts that guest modules are allowed to send requests to. If None or an empty vector is passed, guest modules are NOT allowed to make HTTP requests to any server. (Note that the hosts passed MUST have the protocol also specified - i.e. https://my-domain.com, or http://192.168.0.1, and if making requests to a subdomain, the subdomain MUST be in the allowed list. See the the library tests for more examples).

Note that the Wasmtime version currently supported is 0.26.

Sending HTTP requests from AssemblyScript

This repository also contains an AssemblyScript implementation for sending HTTP requests:

// @ts-ignore
import * as wasi from "as-wasi";
import {
  Method,
  RequestBuilder,
  Response,
} from "@deislabs/wasi-experimental-http";

export function _start_(): void {
  let body = String.UTF8.encode("testing the body");
  let res = new RequestBuilder("https://postman-echo.com/post")
    .header("Content-Type", "text/plain")
    .method(Method.POST)
    .body(body)
    .send();
  wasi.Console.log(res.status.toString());
  wasi.Console.log(res.headersGetAll.toString());
  wasi.Console.log(String.UTF8.decode(res.bodyReadAll().buffer));
}

Testing using the wasmtime-http binary

This project also adds a convenience binary for testing modules with HTTP support, wasmtime-http - a simple program that mimics the wasmtime run command, but also adds support for sending HTTP requests.

➜ cargo run --bin wasmtime-http -- --help
wasmtime-http 0.1.0

USAGE:
    wasmtime-http [OPTIONS] <module> [--] [ARGS]...

FLAGS:
    -h, --help       Prints help information
    -V, --version    Prints version information

OPTIONS:
    -a, --allowed-host <allowed-hosts>...    Host the guest module is allowed to make outbound HTTP requests to
    -i, --invoke <invoke>                    The name of the function to run [default: _start]
    -c, --concurrency <max-concurrency>      The maximum number of concurrent requests a module can make to allowed
                                             hosts
    -e, --env <NAME=VAL>...                  Pass an environment variable to the program

ARGS:
    <module>     The path of the WebAssembly module to run
    <ARGS>...    The arguments to pass to the module```

Known limitations

  • there is no support for streaming HTTP responses, which this means guest modules have to wait until the entire body has been written by the runtime before reading it.
  • request and response bodies are Bytes.
  • the current WITX definitions are experimental, and currently only used to generate guest bindings.
  • this library does not aim to add support for running HTTP servers in WebAssembly.

Code of Conduct

This project has adopted the Microsoft Open Source Code of Conduct.

For more information see the Code of Conduct FAQ or contact [email protected] with any additional questions or comments.


wasi-experimental-http's People

Contributors

dicej avatar jedisct1 avatar maxgraey avatar mossaka avatar radu-matei avatar thomastaylor312 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

wasi-experimental-http's Issues

Streaming responses

Guests currently expect the runtime to finish writing the the entire request before reading it, and it would be very helpful to have support for streaming a response body.

One option would be an additional host function that would use the native HTTP library to read chunked responses, write the chunks in the memory, then populate the pointers representing the chunk start and size.
Then, the guest module would read until the size is not zero.

Rust: complete HTTP request / response support

It would be very nice if the Rust API didn't reimplement the entire HTTP request / response structures from scratch.

The http crate is already used by hyper and reqwest, and it would make sense to allow users to construct requests and get responses back.

This means we would have to decompose its fields (body, method, query params, headers) into buffers and their lengths before making the host call, but users could use the request builder to simplify things:

pub fn request<T, U>(req: Request<T>) -> Result<Response<U>, Error> {
    todo!()
}

Not sure what the type constraints on T and U should be here (most likely Serialize + Sized, but that would have to be checked).

Wasmtime: block on async and `reqwest`

Linker-defined functions cannot be asynchronous yet (see bytecodealliance/wasmtime#2434).

This means the actual host call that performs the HTTP request must at some point block - and depending on how the runtime was started, it is possible for it to just hang right now, and the current implementation is put together without any thought into how other runtimes might need to use this.

let res = match block_on(
client
.request(method, &url)
.headers(headers)
.body(req_body)
.send(),
) {

cc @thomastaylor312

Rename `allowed_domains` and disable all by default

First of all, allowed_domains should actually be allowed_hosts, because the items can be IP addresses, not only domain names.

But more importantly, when passing None, the library currently allows guest modules to make requests to any server, which is counter-intuitive, and directly opposed to how any other capability works.

We should address both of these and release a new version to crates.io.

AssemblyScript: GC finalizer for `Response`

AssemblyScript/assemblyscript#1256 introduced a new GC hook that runs before managed objects before being collected.
This is helpful for Response objects, whose handles have to be manually closed right now, and in theory, we could remove this requirement by implementing the finalizer.

The issue is that Response objects don't seem to be collected - i.e. the console log is never executed here.

@global function __finalize(ptr: usize): void {
    // @ts-ignore
    if (__instanceof(ptr, idof<Response>())) {
        Console.log("running finalizer with ptr: " + ptr.toString())
        // change type to `Response` and call `close`
    }

// @ts-ignore
__collect();

Manually keeping track of Response objects and the collected pointers, it's clear that they are not collected with the current implementation, which could be an indicator that we are actually leaking memory.

Another question is related to manually calling __collect - without manually calling it, the finalizer hook is not always executed. Are there any best practices around manually calling it or not?

cc @jedisct1

`alloc()` function

Hi!

Memory allocations currently rely on exporting an alloc() function.

While this works for Rust, it doesn't play well with Zig, that doesn't hide memory allocations (any function requiring dynamic allocations must accept an allocator as a parameter). This is not going to play well with GC'd languages either.

Maybe the application could call an initialization function, passing a function pointer to the allocation function instead?

WITX definition for the request API

Currently there is no WITX support in this repository - the API is defined and implemented directly for Wasmtime, but if we wanted to support multiple runtimes (and even to keep the two crates in sync), it would be very helpful to have WITX definitions.

Server Support

Thanks for working on this, very useful for experimental WASM work without having to write the wrappers and host functionality manually.

Are you planning on also implementing http server functionality?

Minimal http server functionality would be similarly useful as a POC for wasm server workloads.

I would imagine a simple implementation based on hyper, where the wasm side SDK takes a handler function that receives a Request and returns a Response. No streaming capability, only fully resolved bodies, like the client.

Edit: ah, I noticed the this library does not aim to add support for running HTTP servers in WebAssembly. in the README.
Is there a particular reason for that?

Add a simple binary that can be used for standalone testing modules

Right now, after building a module that contains this library, even if that module is standalone and could be executed with Wasmtime, because of the missing host calls, the test suite in this repo has to be extended before executing the module.

This is time consuming, and it would be helpful to have _something similar to the wasmtime run command that adds this library.

Options

Applications may want to access the content via a proxy. Or to disable certificate verification. Or to limit the bandwidth. Or force HTTP/2 or HTTP/3 usage. Or set whatever knobs a specific runtime provides.

curl has a bazillion options. And applications actually use these.

We can't possibly add extra parameters for all of these, especially as new needs may come up over time.

So, maybe what we can do is introduce an Options handle, on top of which (key, value)-type options can be set.
And the req() function optionally accepts such a handle.

This allows the API to be extended, even with implementation-specific features, without breaking it.

Wildcards for allowed hosts?

With #39, the default behavior of None for allowed_hosts changes from allowing guest modules to make requests to any server to not allowing access to any server.
Additionally, if someone intends to allow access to all subdomains of a particular domain, that is currently impossible, and each subdomain would have to be individually added to the list.

Do we want to add:

  1. A top-level wildcard that would explicitly allow guest modules to send requests to all servers? Perhaps "*" as the only element of the allowed_hosts vector?
  2. The ability to specify a domain wildcard?

Enum for HTTP request method

Right now, the request HTTP method is passed as a string, which takes significantly more memory compared to an single numeric value.
This is not an issue right now, but it could become one for a high number of requests.

This issue tracks this change across the runtime and guest implementations.

Cargo.toml wasi-experimental-http and wasi-experimental-http-wasmtime dependencies: crates.io vs local path?

Hello,

Any thoughs on having the wasi-experimental-http and wasi-experimental-http-wasmtime dependencies (in Cargo.toml) fetched from crates.io, instead of having it referenced in a local path? I presume these dependencies need to also be updated with the latest changes and a new version published in crates.io.

When attempting to reference to the latest version(s): 0.9.0 we get build/run errors.

Thanks!

Cargo.toml:

wasi-experimental-http = "0.9.0"
wasi-experimental-http-wasmtime = "0.9.0"

Output:
'
error[E0308]: mismatched types
--> bin/wasmtime-http.rs:99:9
|
99 | allowed_hosts,
| ^^^^^^^^^^^^^ expected struct Arc, found enum Option
|
= note: expected struct Arc<Option<_>>
found enum Option<_>

error: cannot construct HttpCtx with struct literal syntax due to inaccessible fields
--> bin/wasmtime-http.rs:98:16
|
98 | let http = HttpCtx {
'

Compiling anything that imports `wasi_experimental_http_wasmtime` fails on Windows

This is because the wasi_experimental_http_wasmtime crate imports two functions from the wasi_experimental_http crate, which in turn relies on external symbols (the host functions related to HTTP).

And even if the two functions imported don't actually call any of the external symbols, the Windows linker still fails.

I will investigate if this is a known issue with the linker on Windows, but removing the dependency to wasi_experimental_http solves the issue, and the two functions are simple enough that we can just copy-paste.

  = note: libwasi_experimental_http-c7b972a7a58f275d.rlib(wasi_experimental_http-c7b972a7a58f275d.39shyjq0d6lqu8qa.rcgu.o) : 
error LNK2019: unresolved external symbol __imp_req referenced in function _ZN22wasi_experimental_http3raw3req17h295ccbc09f2fe42dE
          libwasi_experimental_http-c7b972a7a58f275d.rlib(wasi_experimental_http-c7b972a7a58f275d.39shyjq0d6lqu8qa.rcgu.o) : 
error LNK2019: unresolved external symbol __imp_header_get referenced in function _ZN22wasi_experimental_http3raw10header_get17h1870664f7a8646ffE
          libwasi_experimental_http-c7b972a7a58f275d.rlib(wasi_experimental_http-c7b972a7a58f275d.39shyjq0d6lqu8qa.rcgu.o) : 
error LNK2019: unresolved external symbol __imp_headers_get_all referenced in function _ZN22wasi_experimental_http3raw15headers_get_all17hb2f4ccc303974529E
          libwasi_experimental_http-c7b972a7a58f275d.rlib(wasi_experimental_http-c7b972a7a58f275d.39shyjq0d6lqu8qa.rcgu.o) : 
error LNK2019: unresolved external symbol __imp_body_read referenced in function _ZN22wasi_experimental_http3raw9body_read17h4cbd4ef921d4891cE
          D:\projects\deislabs\wasi-experimental-http\target\debug\deps\integration-159d744b0b153291.exe : fatal error LNK1120: 4 unresolved externals

"Destination not allowed" errors are non-descriptive

For example, building an optimized AssemblyScript module and running it, the error is very opaque:

:0:0: error: 
 rror running WASM module: Exited with i32 exit status 1
    wasm backtrace:
        0:  0x6d8 - <unknown>!<wasm function 12>
        1: 0x15a7 - <unknown>!<wasm function 37>
        2: 0x19e6 - <unknown>!<wasm function 40>
    note: run with `WASMTIME_BACKTRACE_DETAILS=1` environment variable to display more information

In a similar way, Rust errors are hard to debug.
We should have a way to explicitly describe why the request failed.

AssemblyScript: `Console.log` of string literal panics

This is a weird error, so I'm opening it sooner rather than later, even with very little info.
Stumbled across this while trying to decode a header value, and it turns out that sometimes trying to Console.log (or Console.write) a string panics.

I haven't tested this outside of the current project, which is why I'm not opening this issue in as-wasi yet.

In short:

let y = "testofastringliteral";
Console.log(y);
thread 'tests::test_with_allowed_domains' panicked at 'called `Result::unwrap()` on an 
`Err` value: wasm trap: out of bounds memory access
wasm backtrace:
    0: 0x13f3 - <unknown>!~lib/rt/itcms/Object#get:color
    1: 0x15aa - <unknown>!~lib/rt/itcms/__visit
    2: 0x15dc - <unknown>!~lib/rt/itcms/visitStack
    3: 0x1dac - <unknown>!~lib/rt/itcms/step
    4: 0x1e79 - <unknown>!~lib/rt/itcms/interrupt
    5: 0x23f7 - <unknown>!~lib/rt/itcms/__new
    6: 0x3fbb - <unknown>!~lib/string/String.UTF8.encode
    7: 0x12e4 - <unknown>!~lib/as-wasi/as-wasi/Descriptor#writeStringLn
    8: 0x1361 - <unknown>!~lib/as-wasi/as-wasi/Descriptor#writeString
    9: 0x3613 - <unknown>!~lib/as-wasi/as-wasi/Console.write
   10: 0x2d31 - <unknown>!~lib/as-wasi/as-wasi/Console.log
   11: 0x395b - <unknown>!../../crates/as/index/Response#headerGet
   12: 0x3a58 - <unknown>!index/check
   13: 0x3be9 - <unknown>!index/post

The weird part is that Console.log("value" + y); will run successfully.

However, the result is that trying to just print a header value simply panics in my WIP branch.
I'll try to reproduce this and update the issue.

Configure logging

Right now, logs are just printed to standard output. It would be very helpful to have configurable logging.

Failing tests related to allowed hosts in AssemblyScript

There is a CI failure first seen in #58:

thread 'tests::test_with_allowed_domains' 
panicked at 'called `Result::unwrap()` on an `Err` value: Exited with i32 exit status 1
wasm backtrace:
    0: 0x33eb - <unknown>!~lib/as-wasi/as-wasi/wasi_abort
    1: 0x431a - <unknown>!index/get
', tests/integration.rs:108:47
test tests::test_with_allowed_domains ... FAILED

Both failing tests seem to be the AssemblyScript ones, and both pass on my machine.
They should just work™ because none of these PRs introduce any changes to the way allowed hosts are handled:

cargo test --package wasi-experimental-http-wasmtime-sample --test integration --all-features -- tests::test_with_allowed_domains --exact --nocapture <

    Finished test [unoptimized + debuginfo] target(s) in 0.07s
     Running target/debug/deps/integration-39ca980876a4470e

running 1 test
module instantiation time: 1.2017504s
module instantiation time: 99.8947ms
test tests::test_with_allowed_domains ... ok

test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 8 filtered out; finished in 2.97s

cargo test --package wasi-experimental-http-wasmtime-sample --test integration --all-features -- tests::test_async_with_allowed_domains --exact --nocapture <

    Finished test [unoptimized + debuginfo] target(s) in 0.06s
     Running target/debug/deps/integration-39ca980876a4470e

running 1 test
module instantiation time: 1.1927142s
module instantiation time: 99.2269ms
test tests::test_async_with_allowed_domains ... ok

test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 8 filtered out; finished in 2.86s

Implement host call to get all headers

Currently, there is no way for a client to get all headers.
This means that if you don't know which response headers you are getting, there is no way to check.

There should be a way to get all headers.

Rust: enum for error code

The error code returned by the runtime is a u32 - there should be a Rust enum that maps the integer to an enum variant, and that should be used in both crates.

Update `as-wasi` dependency in AssemblyScript client

The AssemblyScript implementation is currently pinned to v0.4.4 or as-wasi, and the new release that breaks building modules:

ERROR TS6054: File '~lib/as-wasi.ts' not found.

 import { Console } from "as-wasi";
                         ~~~~~~~~~
 in ~lib/@deislabs/wasi-experimental-http/index.ts(3,25)

We should bump as-wasi (and potentially AssemblyScript itself).

AssemblyScript: support for HTTP requests and responses

The current AssemblyScript implementation is currently not functional - the API is out of sync, and it only has support for handling URLs and string responses.

This issue tracks the completeness of the AssemblyScript support for this library.

Headers

Headers are currently serialized in JSON. At least in the Rust code. In AssemblyScript, they seem to be comma-separated.

The former is quite expensive, the later is unsafe if values contains commas.

According to RFC 7230, only ASCII characters are allowed in headers, not including any control characters besides the horizontal tab. \0 in particular, cannot be in a header value without additional encoding. Separators (including :) cannot be in a header name either.

So, maybe string encoding of headers could simply be <name1>:<value1>\0...<nameN>:<valueN>\0?

This is very simple and safe to parse and serialize in any language.

Add list for allowed domains

Ideally, it would be possible to configure a list of allowed domains that guest modules can make HTTP requests to.

In the current state of the library, this would be passed as an Option<Vec<String>>, and the configuration could be passed from the underlying runtime:

let allowed_domains = vec!["bing.com", "deislabs.io"];
wasi_experimental_http.link_http(&mut linker, Some(allowed_domains))?;

Rust: better crate docs

The current documentation for the crates is minimal at best.
We need to add some more details about how to use them.

Constant lengths as pointers?

Hi,

In the req() function, constant lengths (url, method, body, headers) are passed as pointers.

Is there a reason not to pass them as usize directly and avoid indirections?

Support wasmtime 4.0

When adding wasi-experimental-http-wasmtime to a project using wasmtime version 4.0.0 (latest at the time of writing), cargo complains about versioning conflicts.

      Adding wasi-experimental-http-wasmtime v0.10.0 to dependencies.
error: failed to select a version for `wasi-common`.
    ... required by package `wasi-experimental-http-wasmtime v0.10.0`
    ... which satisfies dependency `wasi-experimental-http-wasmtime = "^0.10.0"` of package `demo v0.1.0 (/Users/bajtos/src/pl/runtime-poc/wasmtime)`
versions that meet the requirements `^0.35` are: 0.35.3, 0.35.2, 0.35.1, 0.35.0

the package `wasi-common` links to the native library `wasi-common-19`, but it conflicts with a previous package which links to `wasi-common-19` as well:
package `wasi-common v4.0.0`
    ... which satisfies dependency `wasi-common = "=4.0.0"` of package `wasi-cap-std-sync v4.0.0`
    ... which satisfies dependency `wasi-cap-std-sync = "=4.0.0"` of package `wasi-tokio v4.0.0`
    ... which satisfies dependency `wasi-tokio = "=4.0.0"` of package `wasmtime-wasi v4.0.0`
    ... which satisfies dependency `wasmtime-wasi = "^4.0.0"` of package `demo v0.1.0 (/Users/bajtos/src/pl/runtime-poc/wasmtime)`
Only one package in the dependency graph may specify the same links value. This helps ensure that only one copy of a native library is linked in the final binary. Try to adjust your dependencies so that only one package uses the links ='wasi-common' value. For more information, see https://doc.rust-lang.org/cargo/reference/resolver.html#links.

FWIW, downgrading my project to wasmtime version 0.35 allowed me to install wasi-experimental-http-wasmtime.

Support trailers

In addition to headers, maybe we want to support HTTP/2 trailers.

These are necessary for gRPC.

Error handling

While HTTP statuses are handled properly, other errors that occur in making the request panic in the runtime - this should not happen, and the error and some context should be sent back to the guest module.

wasi_experimental_http::data_from_memory:: length: 32
wasi_experimental_http::req: URL: https://some.unknown.domain.dev/
wasi_experimental_http::data_from_memory:: length: 13
thread 'main' panicked at 'called `Result::unwrap()` on an `Err` value: reqwest::Error { kind: Request, url: Url { scheme: "https", host: Some(Domain("some.unknown.doma
in.dev")), port: None, path: "/", query: None, fragment: None }, source: hyper::Error(Connect, ConnectError("dns error", Custom { kind: Other, error: "failed to lookup
address information: Name or service not known" })) }', src/lib.rs:46:91
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace

Automate package publishing

We still manually push the three packages to NPM and crates.io -- for example as in #76

I would very much like to automate this process.

Guest: content type and decoding

Some webpages return different text encodings ("content-type": "text/html; charset=ISO-8859-1"), such as ISO-8859-1 - and because the response we return in the library is an uninterpreted byte array, users will have to manually read the content type response header and appropriately decode the body. This is counter-intuitive, as most HTTP libraries will automatically do this.

It would be very helpful if we could provide users with a simple way of automatically decoding the response text based on the content type.

I am not really sure what would be the best way to handle this, but it looks like encoding_rs would be a very good place to start.

cc @technosophos

Limit number of concurrent requests a module can send

There should be a way that the number of concurrent requests can be set when configuring the HTTP library, similar to how the list of allowed hosts is configured.

What should be default if no such limit is set?

HTTP endpoint used in tests changed

The tests are currently failing because the endpoint we have been using in our tests — https://api.brigade.sh/healthz no longer returns "OK" (but an empty response).

In order for the tests to pass, we either need to update the tests to check for an empty response (which is not ideal, because it does not actually check that the response body is handled correctly), or test a different endpoint.
Any ideas?

I will probably put out a PR to fix the failing tests by updating the expected body, but we should find an endpoint that actually helps test the response body properly.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.