crowdhailer / raxx Goto Github PK
View Code? Open in Web Editor NEWInterface for HTTP webservers, frameworks and clients
Home Page: https://hexdocs.pm/raxx
License: Apache License 2.0
Interface for HTTP webservers, frameworks and clients
Home Page: https://hexdocs.pm/raxx
License: Apache License 2.0
Location header should only be set on response status 201 | 3XX
Discussed in this Tokumei issue
The cowboy adapter currently cannot be started under a project applications supervision tree.
Cowboy, by design, starts a server under its application supervision tree when using :cowboy.start_http/4
.
It is possible to start it under a project supervisor. and we would like to add that functionality to the cowboy adapter.
See:
This should be started in a new repo and linked from the extensions section of this repo.
The hex project should be raxx_logger
false
or binary()
rails discusses how this updates looking up client ip
https://github.com/rails/rails/blob/4-2-stable/actionpack/lib/action_dispatch/middleware/remote_ip.rb
maybe this? https://tools.ietf.org/html/draft-petersson-forwarded-for-02
If any callback returns a response with body set to true an error should be raised. This is because the response is incomplete.
e.g.
defmodule MyServer do
use Raxx.Server
def handle_request(request, state) do
response = Raxx.response(:ok)
|> Raxx.set_body(true)
end
end
This example should raise an error
the correct return value is {response, new_state}
https://github.com/elli-lib/elli seems to be in active development.
Should we upgrade?
All examples should have @impl Raxx.Server
used correctly through out the project
This should be started in a new repo and linked from the extensions section of this repo.
The hex project should be raxx_session
A previous implementation exists in the Tokumei project but the new independent implementation must also handle streaming.
https://github.com/CrowdHailer/Tokumei/tree/master/app/lib/tokumei/session
The session method should be pluggable but always decode the session into a raxx.session
header
Note that calls inside
try/1
are not tail recursive since the VM
needs to keep the stacktrace in case an exception happens.
Raxx.ServerSentEvents -> Rack.ServerSentEvents.Handler
Raxx.Handler -> Raxx.{Basic/Core/Request}.Handler
Before this is done applications can just ask for each connection to be closed.
Have an extensible method for handling errors within the main callbacks.
Do we need different error handlers for different call backs. Or can we just have a return value of resolved/not_resolved
I am unclear why elixirs URL library does not support lists when encoding and decoding query strings
URI.decode_query("foo[]=1&foo[]=2")
# %{"foo[]" => "2"}
# But I would expect %{"foo" => ["1", "2"]}
This is obviously a deliberate choice as in the docs is this quote
Keys and values can be any term that implements the String.Chars protocol, except lists which are explicitly forbidden.
elixir-lang/elixir#2876 Suggests just using plug but I will be instead copy and pasting as raxx cannot depend on plug.
Thanks for this simple web server library.
Please can you give an example of how to setup raxx as a secure server, i.e. with ssl.
I have looked at your Elli and Cowboy adaptors, I cannot find where you handle https.
destructing of the Host field gives host and port but also protocol and possibly authority. Though I think that authority is not part of the updated rfc.
Raxx does not yet support cookies. Can follow Rack closely on this respect
Use logger not IO.inspect
on adapter.
so far
Raxx.get
have some master test file for integrations
def ok(body, headers)
def ok(headers)
def ok(%{body: body, headers: headers}, headers)
def ok(json(%{content})
I think there must be some great macro stuff possible here to reduce runtime lookups
defmodule MyApp do
use Raxx.Stack
stack Raxx.Csrf
stack Raxx.Session, secret: "top secret"
stack Raxx.GZip
stack Raxx.Time
stack Raxx.WhoAmI, server_name: "my name"
stack Raxx.ContentLength
stack Raxx.Head
stack Raxx.Scrub, (redirect or rewrite)
mount "/assets", AssetsController
service "/accounts", "accounts.app.consul"
end
Needs to incorporate mime information. Elixir has a mime library.
https://github.com/elixir-lang/mime
Long poll should just await within function
https://24ways.org/2016/http2-server-push-and-service-workers/
https://github.com/phoenixframework/phoenix/blob/v1.2.3/lib/phoenix/transports/long_poll.ex#L1
[state, [{target, message]
%Response{state: :completed, promises: []}
middleware to fetch promises from response links
(server-process) -> (handler-process)
kill handler process after replying.
Good for HTTP2
@expect-continue true
def handle_request(r, c) do
body = body(r) # memoised
{{__MODULE__, c}, [%Response{body: nil}] # chunked
{{__MODULE__, c}, []} # longpoll
{nil, [%Response{body: nil}, promise("/favicon.ico")] # with server push
end
with mailbox monad
def handle_request(r, c) do
reply(response)
promise("favicon.ico")
end
def handle_request(r, c) do
upgrade(__MODULE__, :awaiting)
end
def handle_info(message) do
reply(response)
end
defmodule Ping.Ready do
receive config do
Request(path: ["event", id]) ->
send(MyApp.PubSub, {self, id})
send(:timer, 10_000)
Ping.Awaiting, config
end
end
defmodule Ping.Awaiting do
receive config do
PubSub.update(contents) ->
send(MyApp.PubSub, {self, id})
reply(ok("content"))
Raxx.Completed # could call a close state here
end
end
Add dialyxir to this project and typespecs to all public functions. The benefits of this are improved documentation as well as an extra layer of checks.
Running dialyzer should become part of the travis test action.
If we respond to a request with Connection: close
, we should send a response with Connection: close
and then close it ourselves.
This works around buggy clients that send Connection: close
and never close the connection themselves.
Hey!
Could you document the recommended approach of testing raxx apps please? Are there some handy helper functions we can use? :)
Cheers,
Louis
Very simple example of sending events with elixir
https://gist.github.com/rbishop/e7b1886d5e75b2f74d8b
This is a refactoring issue.
The functionality in http_status should be contained with in the core raxx project. there is no need to have it separate. Also a reason phrase is not part of the HTTP/2 specification.
The function for generating a response start line should also not add a newline character.
The http_status package should be retired on hex.
Should be able to send data content with newline characters in it.
Best to testby property testing encode/decode.
The test step should fail if any compiler warnings are emitted. This condition should be added to the travis setup so that PR's will fail with any new warnings.
There seams to be some discussion around a --warnings-as-errors
option to mix compile
but I could not make it work.
Lines 258 to 260 in a73694e
We don't need to raise an error here. See this: https://stackoverflow.com/a/5259004/44080
RFC 7230 explicitly states that field headers should be treated as case insensitive
Host should not start as www.example.com
Set up a Raxx.Default
module that is included by Raxx.Server
use this new module in example cases for is_application?
tests.
This will have to wait until the new year when elixir 1.6
is released. The CI tests should fail if running the formatter would result in a change to the code.
Not sure if such a mix task even exists, but I think it would be good. It would however mean that raxx required 1.6 to work.
use
mix format --check-formatted mix.exs "{lib,test}/**/*.{ex,exs}"
copy from plug.
also use the pattern
{buffer, partial}
Can be a middleware layer.
parsing as a stream to go with other middleware stuff. return a list so buffer can contain many parts
headers should be an extensible concept.
Consider having a module for each header eg Raxx.ContentType
then other libraries can just implement Raxx.XMyHeader
RFC 7230
RFC 7231
RFC 7232
RFC 7233
RFC 7234
RFC 7235
RFC 6265
http is a request response protocol. counter to jose post.
the plug object has a growing complexity
https://gist.github.com/jamonholmgren/fc3b995d2704b1780b55
if the request has already been partially routed. this is the same as rack SCRIPT_NAME, (I believe)
All information in the host header is duplicated in other parts the request struct.
The Host header is always required.
Therefore should the host header be deleted from this list of headers?
It should never be relied on and users building request might add a host field but not a host header
Can the Host
header have a path in the URL?
Raxx.Request.host + Raxx.Request.mount = virtual host
Router.host instead of Router.mount
In HTTP/2 can the authority header have a path component
Started some reading around webservers other than cowboy.
checkout the following resources.
Take the better errors implementation in plug and port to raxx. Would be nice if can be first example of pluggable error handler. #8
This line will only match requests where the query had not been set
def set_query(request = %Raxx.Request{query: nil}, query) do
What if we want to set / append / or change the existing query?
for logging really.
maybe called inspect
get "/path" (Host: example.com) (Cookie: foo=bar)
List of decisions to be made before releasing 1.0
handle_headers
a confusing name for a callback? I think perhaps the following might be clearer
handle_head/2
handle_body/2
handle_tail/2
handle_info/2
Raxx.Server
and Raxx.TransferEncoding
Raxx.Fragment
does not need end_stream
attributeRaxx.Fragment
to Raxx.Body
Raxx.Server
to Raxx.Spec
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.