All notable changes to this project will be documented in this file.
The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.
- Require safety documentation for unsafe blocks.
- Fixed FromRequest for
alloc::vec::Vec
, and by extension,alloc::string::String
.
picoserve::response::chunked::ChunkWriter::write_chunk
no longer flushes the socket.- Removed workaround for embassy-net TcpSocket::flush() never finishing due to upstream bugfix.
- Tidied Content implementation of containers (e.g. Vec and String).
impl<C: Content> IntoResponse for C
- Fixed
--inline-threshold
deprecation warning inembassy
examples.
- Created an embassy example
app_with_props
to demonstrate building an app with build properties.
- Fixed documentation URLs
- Updated to embassy-net 0.5, which has a breaking change.
- Since Rust 1.81, the TAIT (Trait In Type Aliases) usage is disallowed. Added helper traits
picoserve::AppBuilder
andpicoserve::AppWithStateBuilder
to simplify creating a static app using ITIAT (Impl Trait In Associated Type).
- Examples use ITIAT (Impl Trait In Associated Type) instead of TAIT (Trait In Type Aliases).
- Fixed return type of
picoserve::routing::Router::nest
.
- Added example demonstrating nesting
Router
s. - Added support for "PUT" and "DELETE" HTTP methods.
alloc::string::String
now implements IntoResponse (previouslystd::string::String
did).
Debug2Format
implements "core::fmt::Debug"
- Added support for deserializing JSON values using the Json Extractor.
- Deprecated and removed
ShutdownMethod
,Config::shutdown_connection_on_close
,Config::abort_connection_on_close
,Socket::abort
. <embassy_net::tcp::TcpSocket as picoserve::io::Socket>::shutdown
now aborts the flush once the socket state isClosed
.File
no longer implementsIntoResponse
.
- No longer flushing forever if the already closed while an
embassy_net::tcp::TcpSocket
socket is shutting down. - Fixed bug in
<ETag as PartialEq<[u8]>>::eq
.
- Changed where the socket is flushed, avoid double-flushes.
- Layers can take ownership of requests, allowing them to:
- Route requests to a different Router.
- Not call the next layer, but return a response.
- Implemented Chunked Transfer Encoding.
- Added CustomResponse, allowing for responses with a body that doesn’t match a regular HTTP response.
FrameWriter
now implements flush, which just flushes its internal writer. Resolves potential future correctness issues.- Removed unnessessary
unsafe
code inFormatBuffer
- Disabled decoding escape sequences in Headers, as was incorrectly implemented, and in fact escape sequences are deprecated.
- Headers are
[u8]
notstr
, to allow header names and values that are not UTF-8. - Correctly handling zero-length Web Socket payloads.
- SSE Data can now contain newlines.
- SSE Data can now be a
core::fmt::Arguments
, as produced byformat_args!
. - Web Sockets can now send
core::fmt::Arguments
as a series of text frames, allowing for sending formatted text messages.
- Added Router::from_service which creates a Router from a PathRouterService, allowing a custom fallback service should routing fail to find a suitable handler or service. Added
routing_fallback
example to demonstrate this.
- Added double quote to the list of allowed characters in headers.
- Optionally abort the connection instead of performing a graceful shutdown after handling all requests.
- Fixed compilation errors when enabling "defmt" feature.
- Several public types have changed name to improve name consistency.
- Sealed RequestHandler, MethodHandler, and PathRouter, and added RequestHandlerService and PathRouterService which have better ergonomics.
- A service with no path parameters now has path parameters of
()
notNoPathParameters
. - A service with a single path parameter now has path parameters of
(T,)
, notOnePathParameter
. - A service with multiple path parameters now has a tuple of path parameters, not
ManyPathParameters
.
- A service with no path parameters now has path parameters of
- Moved Status Code constants to inside StatusCode.
- FromRequest and FromRequestParts are now generic over the lifetime of the request, allowing them to borrow from the request.
- Logging using the
log
crate is only enabled if thelog
feature is enabled
- Added from_request and from_request_parts as convenience for PathRouters, and added RequestHandlerServices which borrow from Requests, which is now permitted.
- Added support for percent-encoding in headers.
- If the
defmt
feature is enabled:- All public type which implement
Debug
also implementdefmt::Format
- Logging is done using
defmt
- All public type which implement
File
now has optional headers, allowed for fixed headers to be declared per fileContent
is implemented forVec<u8>
andString
behind thealloc
feature
- Request bodies are no longer automatically read, but must be read.
request::Reader
is no longer public.- Connection must be given an
UpgradeToken
when upgraded. ResponseWriter
must be given aConnection
when writing the response.
- Request Bodies can not be either read into the internal buffer (as previously), or converted into a
RequestBodyReader
, which implements Read.
- Added several unit tests around routing and reading requests.
- Fixed newline in WebSocketKeyHeaderMissing message.
serve
andserve_with_state
now take a socket rather than a reader and writer.
- The socket is now shut down after it has finished handling requests
- Added support for
embassy
with theembassy
feature.- No need to declare and pass in a timer, used Embassy timers
- Pass a
TcpSocket
toserve
andserve_with_state
- Added more examples which use embassy
- Using const_sha from crates.io (rather than copied into this repository) as it now has no_std support
- Config::new is now const
- The "Connection" header is no longer sent in duplicate if the handler has already sent it
- The handling of the "Connection" header in the request has changed:
- If
picoserve
has been configured to always close the connection after responding, set the "Connection" header to "close".- This is the default, overide by calling
keep_connection_alive
on Config.
- This is the default, overide by calling
- If not:
- If the "Connection" header is missing, then check the HTTP version. If the HTTP version is equal to "HTTP/1.1", then keep the connection alive, else close the connection.
- If the "Connection" header is "close", close the connection.
- If the "Connection" header is a comma separated list and one of the entries is "upgrade", such as a websocket upgrade, close the connection after handling the response. Either the handler will handle the upgrade, setting the "Connection" header, in which case it will not also be automatically sent, or something has gone wrong, and the connection should be closed. Also, an upgraded connection, which is thus no longer HTTP, should be closed after completion, not reused.
- Note that the connection is closed after the "response" has been sent. In the case of websockets, sending the "response" includes sending messages to the client and also parsing incoming messages, so this is fine.
- If
- The title of the web_sockets example has been changed from "Server-Sent Events" to "Websockets"
- Frame, Control, Data, and Message in
response::ws
now implement Debug
- Changed Config structure
- Moved timeouts to separate structure
- Added
connection
field, describing behaviour after the response has been sent
- Defaults to closing connection after the response has been sent
- To preserve previous behaviour, which requires multiple concurrent sockets accepting connections, call
keep_connection_alive
on Config
- To preserve previous behaviour, which requires multiple concurrent sockets accepting connections, call
- Allow configuration of behaviour after the response has been sent, i.e. should the TCP connection be closed or kept alive?
- If the request does not include the "Connection" header or it is set to "close", the response includes a header of "Connection: close", and the connection is closed after the response has been sent. Otherwise, the response includes a header of "Connection: keep-alive", and the connection is kept alive after the response has been sent, allowing additional requests to be made on the same TCP connection.
picoserve now runs on stable!
- No longer using the
async_fn_in_trait
feature hello_world_embassy
example uses newer version ofembassy
(and still requires nightly rust due toembassy
using featuretype_alias_impl_trait
)
- Fixed JSON serialization for empty objects and arrays
- Parsing Query and Form now ignores blank space between two
&
characters- This allows urls which end in
?
but have no query, and urls for which there's a&
after the query
- This allows urls which end in
- If
write_timeout
isSome(timeout)
in Config, writing data to the client will fail withError::WriteTimeout
if the write times out
- Improved documentation
- Added
into_response(self)
method to response::fs::File, response::json::Json, and response::sse::EventStream, converting them into a response::Response - Added documentation to response::Response
- Fixed documentation to match changes to rust version
nightly-2023-10-02
, changed in 0.2.0
- Updated
embedded-io-async
to 0.6.0 - Many methods return
SomeErrorType
notpicoserve::io::WriteAllError<SomeErrorType>
- Now using rust
nightly-2023-10-02
- Added hello_world_embassy example to README
- First Release