Code Monkey home page Code Monkey logo

wai's Introduction

An interface between Haskell web frameworks and web servers.

Build status

A Haskell web application targets WAI and then can be deployed to any backend with a WAI adaptor. The premier WAI backend is the Warp web server.

WAI also adds modularity and code-sharing through middleware and WAI applications. Code can be written that works with any web framework targeting WAI.

Documentation

Haddock Documentation

wai's People

Contributors

awpr avatar banacorn avatar basvandijk avatar brechtserckx avatar creichert avatar davecturner avatar erikd avatar goertzenator avatar gregwebs avatar hce avatar kazu-yamamoto avatar lucasdicioccio avatar luite avatar maxgabriel avatar mbg avatar meteficha avatar mgmeier avatar mschristiansen avatar pbrisbin avatar pearcedavis avatar pparkkin avatar snoyberg avatar soenkehahn avatar softmechanics avatar sol avatar sordina avatar tarleb avatar thomasjm avatar tolysz avatar vlix 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  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

wai's Issues

releasing new Warp

Hello,

The new Warp has been running stably in the real world.
Since the new Warp does not break backward compatibility, I guess it's a good time to release it.
Please merge the refactoring branch to master and release the new warp.

[wai-extra] Some proposed additions

I've put up at https://gist.github.com/3344927 some code that I'm proposing being included in wai-extra. Not sure which module(s) it all belongs in, this is all just odd and ends that I've found very useful when working with WAI that don't really in any other package I have or plan to have. I mean, I could create my own wai-extra-singpolyma, or wai-singpolyma-util, but I thought I'd submit here first :)

wai-websockets does not close connections correctly

These two programs should behave the same when faced with websockets requests, the first works with websockets runServer, the second with warp and wai-websockets intercept:

import qualified Network.WebSockets as WS

app :: WS.Request -> WS.WebSockets WS.Hybi00 ()
app rq = WS.acceptRequest rq >> return ()

main :: IO ()
main = WS.runServer "127.0.0.1" 8081 app
import qualified Network.Wai.Handler.Warp as W
import qualified Network.Wai.Handler.WebSockets as WWS
import qualified Network.WebSockets as WS

app :: WS.Request -> WS.WebSockets WS.Hybi00 ()
app rq = WS.acceptRequest rq >> return ()

main :: IO ()
main = W.runSettings sett undefined 
  where
    sett = W.defaultSettings { W.settingsIntercept = WWS.intercept app
                             , W.settingsPort      = 8081
                             }

So they simply accept the request and return. However, they behave differently. If I try to make a request with the "native" version, I reasonably get a ConnectionClose exception:

>>> ws = websocket.create_connection("ws://localhost:8081/")
>>> ws.recv()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/home/rostayob/src/sockjs-protocol/venv/local/lib/python2.7/site-packages/websocket.py", line 347, in recv
    b = self._recv(1)
  File "/home/rostayob/src/sockjs-protocol/venv/local/lib/python2.7/site-packages/websocket.py", line 411, in _recv
    raise ConnectionClosedException()
websocket.ConnectionClosedException

With the wai-websockets version, it just hangs, and I need to terminate it:

>>> ws = websocket.create_connection("ws://localhost:8081/")
>>> ws.recv()
^C

I tried executing the closeConn Connection action after this line but it didn't work - the code to use the Iteratee as a Source looks right to my inexperienced eyes...

Incomplete response can be returned if gzip middleware is used.

When my WAI application returns a response with long content, the response body is not completely output.

The following code reproduces it.
https://gist.github.com/2980993#file_test_with_cgi.hs

Here is a result of executing the program on my environment:

% REMOTE_ADDR=localhost HTTP_ACCEPT_ENCODING=gzip runghc test_with_cgi.hs | sed -e '1,4d' | gunzip
BEGIN123456789101112131415161718192021222324252627282930313233343536373839404142
43444546474849505152535455565758596061626364656667686970717273747576777879808182
---[very long lines]---
94059940699407994089940999410994119941299413994149941599416994179941899419994209
942199422994239942499425994269942799428994299
gzip: stdin: unexpected end of file

If it finishes correctly, its output must ends with characters "END".

Without "Accept-Encoding: gzip", it works fine as follows:

% REMOTE_ADDR=localhost runghc test_with_cgi.hs
Status: 200 OK
Content-Type: text/plain

BEGIN123456789101112131415161718192021222324252627282930313233343536373839404142
43444546474849505152535455565758596061626364656667686970717273747576777879808182
---[very long lines]---
99819998299983999849998599986999879998899989999909999199992999939999499995999969
99979999899999100000END

From my observation, it seems that Data.Conduit.Zlib.compressFlush is not flushed at the end of a response stream.

Thanks.

ipv6 default for warp causes some problems

Warp tries to open an ipv6 socket if one is available, but this seems to cause problems for some users. Many people probably expect a server to respond to 127.0.0.1, and not all platforms forward connections automatically to v6 (there was a user who reported problems in #yesod, on Windows, don't know if he also had trouble connecting to http;//localhost ). Happstack defaults to opening an ipv4 socket because of this.

We can solve this in a number of ways:

  • change the defaultSettings settingsHost "*" to "0.0.0.0"
  • leave defaultSettings host "*", but add a field to indicate whether we prefer v4 or v6
  • same as above, but fail if the preferred socket type is not available for the chosen settingsHost.

The first one is the easiest, perhaps we can add the old default settings back with defaultSettingsPreferIpv6 ?

Any thoughts, any disadvantages of using a 0.0.0.0 bind address to force ipv4?

How to send response to client on Exception?

For now warp can only print application-generated errors to stderr. But the client does not receive anything (324 ERR_EMPTY_RESPONSE).

How to send response to client (500 ...)? Maybe it's Wai question. But I cant use Applications with catch.

warp-tls: Please document how to serve HTTP and HTTPS from the same server

I'd like to serve both HTTP and HTTPS from the same Yesod-based application, using the same event loop. In my case, I'd like to have all HTTP requests redirect to HTTPS; other applications might wish to serve some requests via HTTP and other requests via HTTPS. Either way, I don't want to have to run a separate application or web server just to serve these redirects. Please consider adding documentation (to warp-tls or some other appropriate place) showing how to handle both HTTP and HTTPS from the same Yesod app.

warp-tls fails to build

Current git HEAD:

Building warp-tls-1.3.0.2...
Preprocessing library warp-tls-1.3.0.2...
[1 of 1] Compiling Network.Wai.Handler.WarpTLS ( Network/Wai/Handler/WarpTLS.hs, dist/build/Network/Wai/Handler/WarpTLS.o )

Network/Wai/Handler/WarpTLS.hs:81:33:
    Couldn't match expected type `IO ()' with actual type `()'
    Expected type: warp-1.3.2:Network.Wai.Handler.Warp.Types.Cleaner
               -> IO ()
      Actual type: warp-1.3.2:Network.Wai.Handler.Warp.Types.Cleaner
               -> ()
    In a stmt of a 'do' block:
      C.runResourceT
      $ sourceFileRange fp (Just offset) (Just len)
        C.$$ CL.mapM_ (TLS.sendData ctx . L.fromChunks . return)

and so on.

304 not modified requests timing out

I've run into a problem with static files (with yesod staticFiles) causing timeouts if the status is 304 not modified. If I force a reload, then it works ok.

My setup:
OS X 10.7.1
nginx 1.0.7 reverse proxy from localhost -> localhost:3000

Blake Rain has encountered the same issue on linux, with Apache reverse proxy

Include support for conduit 0.5

This version is not yet released, but should be supported by the next major release of the wai ecosystem. Will likely not require any changes to wai itself except a version bump.

wai-handler-fastcgi fails to install

Trying to build wai (via scripts/install) for yesod 0.10 on OSX 10.7.3 yields this:

Resolving dependencies...
Downloading wai-1.0.0...
Configuring wai-1.0.0...
Preprocessing library wai-1.0.0...
Building wai-1.0.0...
[1 of 1] Compiling Network.Wai      ( Network/Wai.hs, dist/build/Network/Wai.o )
Registering wai-1.0.0...
Installing library in
/Users/jdt/Code/Haskell/.virthualenv/cabal/lib/wai-1.0.0/ghc-7.0.4
Registering wai-1.0.0...
Downloading wai-extra-1.0.0.1...
Configuring wai-extra-1.0.0.1...
Preprocessing library wai-extra-1.0.0.1...
Preprocessing test suites for wai-extra-1.0.0.1...
Building wai-extra-1.0.0.1...
[ 1 of 11] Compiling Network.Wai.Middleware.Vhost ( Network/Wai/Middleware/Vhost.hs, dist/build/Network/Wai/Middleware/Vhost.o )
[ 2 of 11] Compiling Network.Wai.Middleware.Rewrite ( Network/Wai/Middleware/Rewrite.hs, dist/build/Network/Wai/Middleware/Rewrite.o )
[ 3 of 11] Compiling Network.Wai.Middleware.MethodOverride ( Network/Wai/Middleware/MethodOverride.hs, dist/build/Network/Wai/Middleware/MethodOverride.o )
[ 4 of 11] Compiling Network.Wai.Middleware.Jsonp ( Network/Wai/Middleware/Jsonp.hs, dist/build/Network/Wai/Middleware/Jsonp.o )
[ 5 of 11] Compiling Network.Wai.Middleware.Gzip ( Network/Wai/Middleware/Gzip.hs, dist/build/Network/Wai/Middleware/Gzip.o )
[ 6 of 11] Compiling Network.Wai.Parse ( Network/Wai/Parse.hs, dist/build/Network/Wai/Parse.o )

Network/Wai/Parse.hs:141:41:
    Not in scope: data constructor `C.PreparedConduit'
cabal: Error: some packages failed to install:
wai-extra-1.0.0.1 failed during the building phase. The exception was:
ExitFailure 1
wai-handler-fastcgi-1.0.0 depends on wai-extra-1.0.0.1 which failed to install.

releasing warp

May I ask to release warp? I would like to release Mighttpd based on it.

Warp -Werror failure (Prelude catch deprecated for Control.Exception.catch)

Building warp-1.1.0...
[1 of 4] Compiling Paths_warp       ( dist/build/autogen/Paths_warp.hs, dist/build/Paths_warp.o )

<no location info>:
Failing due to -Werror.

Implicit import declaration:
    Warning: In the use of `catch'
             (imported from Prelude, but defined in System.IO.Error):
             Deprecated: "Please use the new exceptions variant, Control.Exception.catch"

Bigger excerpt:

[...]
Building wai-handler-fastcgi-1.1.0...
[1 of 1] Compiling Network.Wai.Handler.FastCGI ( dist/build/Network/Wai/Handler/FastCGI.hs, dist/build/Network/Wai/Handler/FastCGI.o )
Registering wai-handler-fastcgi-1.1.0...
Installing library in
/home/bryce/.cabal/lib/wai-handler-fastcgi-1.1.0/ghc-7.2.2
Registering wai-handler-fastcgi-1.1.0...
Configuring wai-handler-scgi-1.1.0...
Preprocessing library wai-handler-scgi-1.1.0...
Building wai-handler-scgi-1.1.0...
Registering wai-handler-scgi-1.1.0...
Installing library in /home/bryce/.cabal/lib/wai-handler-scgi-1.1.0/ghc-7.2.2
Registering wai-handler-scgi-1.1.0...
Configuring wai-test-1.1.0...
Preprocessing library wai-test-1.1.0...
Building wai-test-1.1.0...
Registering wai-test-1.1.0...
Installing library in /home/bryce/.cabal/lib/wai-test-1.1.0/ghc-7.2.2
Registering wai-test-1.1.0...
Configuring warp-1.1.0...
Preprocessing library warp-1.1.0...
Preprocessing test suites for warp-1.1.0...
Building warp-1.1.0...
[1 of 4] Compiling Paths_warp       ( dist/build/autogen/Paths_warp.hs, dist/build/Paths_warp.o )

<no location info>:
Failing due to -Werror.

Implicit import declaration:
    Warning: In the use of `catch'
             (imported from Prelude, but defined in System.IO.Error):
             Deprecated: "Please use the new exceptions variant, Control.Exception.catch"
cabal: Error: some packages failed to install:
wai-eventsource-1.1.0 depends on warp-1.1.0 which failed to install.
wai-handler-launch-1.1.0 depends on warp-1.1.0 which failed to install.
wai-websockets-1.1.0 depends on warp-1.1.0 which failed to install.
warp-1.1.0 failed during the building phase. The exception was:
ExitFailure 1
warp-static-1.1.0 depends on warp-1.1.0 which failed to install.
warp-tls-1.1.0 depends on warp-1.1.0 which failed to install.
installation failure!
If you are just installing and haven't mucked with the code,
please report this to the mail list at http://groups.google.com/group/yesodweb
or on the issue tracker at http://github.com/yesodweb/issues

I'm sure I'm doing something wrong, so I apologize in advance.

IO

Hello!

Is there a special reason why almost everything in Wai and friends is tied to IO?

Network.Wai.Handler.Launch.run fails on MacOSX

I'm trying to run an application with

main :: IO ()
main = do
app <- toWaiApp HelloWorld
HL.runUrlPort 30001 "" app

The HelloWorld Yesod App is the one from the book.
Executing this gives me the error:
bind: unsupported operation (Can't assign requested address)
I also tried to simply execute run with the default port, but it gives me same error message.

I'm on MacOS X 10.7.4 and ghc-7.4.1

Regards,
Michael

tighten fast-logger dependency of wai-extra 1.2.0.5

Due to the release of fast-logger-0.2, compilation of wai-extra versions 1.2.* break, as their version restriction to fast-logger (โ‰ฅ0.0.2) is too weak. It should be

fast-logger == 0.0.*

or probably better

fast-logger == 0.0.2

Please release warp

Please release the next version of warp which uses simple-sendfile v0.2.4. Thanks in advance.

Dependencies. Again

Same as in #43. Is it possible to release "dependent" versions as soon as possible? Or, relax restrictions on dependencies versions.

ConnectionClosedByPeer vs IncompleteHeaders

Since [1] deleted ConnectionClosedByPeer, we cannot distinguish ConnectionClosedByPeer and IncompleteHeaders. Are there any ways to distinguish them with Conduit?

One idea is that if a buffer is empty and pull returns null bytestring, we take it as ConnectionClosedByPeer. Does this make sense? Is it possible to implement this idea? (I'm not familiar to the internal of Conduit, so I cannot.)

[1] 70bb530

No redirect when using warp-tls

When I configure my site with warp-tls, http traffic is sent to a page with the contents of:

http://pastebin.com/tuthyb5A

HTTPS traffic works fine.

Can this be changed to redirecting to the https site automatically? I don't know how this is done on a low level, but it's possible! I swear!

warp-tls is prone to BEAST attack

Hi

Let me first thank you for your efforts. Yesod is awesome, and Conduits is the data processing model I've always wanted.

I am now running Warp on ports 80 & 443, and some SSL analysis site says it's prone to the BEAST attack.

Removing the MD5/RC4 ciphers from warp-tls did not help. Sorry that I cannot come up with a patch as I don't have much understanding about the issue, but other users may be bothered about this as well.

wai-websockets doesn't work with Hybi00

The Hybi00 spec, in the handshake section, specifies that there have to be 8 bytes at the end that make up the 128bit key necessary for the handshake.

The problem is that warp throws those last 8 bytes away, since they're not part of the headers, and there is no "content-length" header. This makes Hybi00 unusable with wai-websockets, and if you try to make a request it just hangs here since the websockets library is trying to get 8 bytes that are not there.

I'm not sure if this problem has a simple solution, I'd guess it doesn't given the current warp API.

Difference in behaviour : warp vs warp-tls

I was having some troubles with warp-tls giving me a "data: end of file" failure.

I tried debugging this myself, but wasn't able to make much progress. However, during my debugging I came up with a (relatively) simple test program that shows the problem (I'll add it as an attachment, warp-tls-test.hs).

When the test program is run as:

runghc warp-tls-test.hs

it sets up a warp server with a simple WAI Application and uses http-conduit read from the server. This works as expected.

However, when the test program is run as:

runghc warp-tls-test.hs tls

it sets up a warp-tls server instead of a warp server and uses http-conduit to access the server using HTTPS instead of HTTP. This fails.

My debugging suggests that the failure occurs when warp-tls is parsing the HTTP request, but I'm not making much progress debugging this further.

ssGetMimeType encourages inefficient code.

ssGetMimeType is invoked for each FileResponse in wai-app-static. That means if someone writes ssGetMimeType to lookup from a file, that file will be read each time.

Can the type signature be changed to be pure? What is the IO needed for?

Warp doesn't support chunked requests

HTTP/1.1 requests are allowed to use the chunked transfer encoding scheme, but Warp currently only recognizes a request entity if there's a content-length header.

listen on unix socket

small feature request picked up from the #yesod irc channel: it would be nice if Warp supported listening on unix sockets
(nginx supports proxying to unix sockets, managing multiple yesod apps might be easier with sockets, since you don't have to manage free port numbers, and performance would likely be slightly better)

Clean up wai-extra's BackEnd

wai-extra contains a BackEnd for dealing with file uploads. This could be much more nicely integrated with conduit. Let's go ahead and do so for the next major release.

Make wai-extra's BackEnd more configurable

By default tempFileBackEnd uses whatever getTemporaryDirectory function returns and a specific temporary file pattern "webenc.buf".

I would be nice to have that bits configurable, for example by making a more generic function that accept parameters for these two parts.

-- | Save uploaded files on disk as temporary files
tempFileBackEnd :: BackEnd FilePath
tempFileBackEnd = tempFileBackEndOpts getTemporaryDirectory "webenc.buf"

tempFileBackEndOpts getTmpDir pattern = BackEnd
{ initialize = do
tempDir <- getTmpDir
openBinaryTempFile tempDir pattern
, append = (fp, h) bs -> S.hPut h bs >> return (fp, h)
, close = (fp, h) -> do
hClose h
return fp
, finalize = \fp -> removeFile fp
}

Separating Mime stuff

I would like to extract mime stuff from wai-app-static and create a new package like "mime-types".

Background: I would like to test #52 with mighttpd2. mighttpd2 depends on wai-app-file-cgi, which depends
on wai-app-static because of mime types. But wai-app-static depends on crypto-conduit whose version 0.5.0
is not available from HackageDB. From the wai-app-file-cgi point of view, wai-app-static is heavy.

So, I would like to have a light package like "mime-types".

wai-websockets headers

i think there might be a header parsing problem - I'm playing around with Jasper's websocket stuff, and when i dump the request headers inside the intercept funciton, i get this:

[("Upgrade","WebSocket\r"),("Connection","Upgrade"),("Host","\192.\168:9160\r"),("Origin","ArduinoWebSocketClient\r")]

in this case, it fails to intercept because it's looking for "WebSocket", without the "\r".

http://tools.ietf.org/html/rfc2616#page-31 seems to suggest that you have to handle CR, LF or CRLF.

i think I have some further problems with case of headers, but that's more my problem :)

remove Network.Wai.Middleware.Debug module

I am including this functionality in the new RequestLogger module. I think this name is better - there are many possible things that could be debugged. Users should require a change to a single import statement.

Constructing URLs

serverName and serverPort both say they should not be used in constructing URLs. Fine. What, then, should be used?

ReadInt code doesn't compile with GHC 7.4

Hey @erikd

I get the following error message compiling on 7.4.

ReadInt.hs:37:27:
    Couldn't match kind `#' against `*'
    In the first argument of `I#', namely
      `(word2Int# $ indexWord8OffAddr# addr (ord# i))'
    In the expression:
      I# (word2Int# $ indexWord8OffAddr# addr (ord# i))
    In an equation for `mhDigitToInt':
        mhDigitToInt (C# i)
          = I# (word2Int# $ indexWord8OffAddr# addr (ord# i))
          where
              !(Table addr) = table
              table :: Table
              table
                = Table
                   "\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\SOH\STX\ETX\EOT\ENQ\ACK\a\b\t\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL"#

The easy fix is to revert to digitToInt, but that's obviously not too efficient. I don't mind using that as a stop-gap measure until you have a chance to look at this, just let me know.

test.hs is broken

The test.hs file (and, perhaps, other files in the project) is broken, referencing modules that no longer exist. It should be removed or, preferably, replaced with an example that tests and demonstrates the same features.

Experience some problem on OS X

Hi!

I wanted to try warp to serve my static website. And I then tried to use the Apache Benchmark tool ab to make some test.

I tried both on Ubuntu Linux and on OS X Lion 10.7.

On Lion I experience some error messages from the server:

Network.SendFile.MacOS.sendPart: invalid argument (Socket is not connected)
Network.SendFile.MacOS.sendPart: resource vanished (Broken pipe)

And a lot of error message from the ab tool. It returns the following errors:

a lot of "Send request failed!"
and time to time a "apr_socket_recv: Connection reset by peer (54)

I have installed the 64bit Haskell Platform. And I had launched my website with the following command:

warp -d output

I used the following command line:

ab -c 20 -n 10000 http://localhost:3000/Scratch/en/blog/Learn-Vim-Progressively/index.html

Furthermore, I believe it hurts the efficiency of warp-static. As if I use the -r option on the ab tool not to stop at first error, the result are similar to the one I have on my Linux platform, except, my Mac is generally about 5x faster than the Linux I use.

Warp cannot handle "Transfer-Encoding: chunked" requests

When sending POST requests to Warp with "Transfer-Encoding: chunked" (like Go does when serializing byte arrays).

Here's the Server I used for testing:

{-# LANGUAGE OverloadedStrings #-}
module Main
where

import Network.Wai.Handler.Warp (run)
import Network.Wai
import Network.HTTP.Types

app :: Application
app req = return $ responseLBS
    status200
    [("Content-Type", "text/plain")]
    "Responsetext"

main :: IO ()
main = do
    run 8080 app

Here's the client I used for testing (takes two parameters, one for the number of concurrent requests, and one to set the total number of requests).

For exmple, 10 clients and 10000 requests: go run rest-tester.go 10 10000

To disable Transfer-Encoding: chunked, replace "bytes" with "strings" (switch the comments).

package main

import (
    "net/http"
    "fmt"
    "bytes"
    //"strings"
    "os"
    "strconv"
    "time"
    "runtime"
)

var client = &http.Client{}

func createDocument() {
    requestBodyReader := bytes.NewReader([]byte(`some text`))
    //requestBodyReader := strings.NewReader("some text")
    res, err := client.Post("http://localhost:8080", "text/plain", requestBodyReader)
    if err != nil {
        fmt.Println("Post failed", err, time.Now())
        os.Exit(1)
    }
    fmt.Println("ok")
    res.Body.Close()
}

func doOneDoc(i int, c chan string) {
    for {
        <-c // wait for ok
        createDocument()
    }
}

func main() {
    cpuNum, _ := strconv.Atoi(os.Args[1])
    docNum, _ := strconv.Atoi(os.Args[2])
    runtime.GOMAXPROCS(cpuNum)
    c := make(chan string)

    for i := 0; i < cpuNum; i++ {
        go doOneDoc(i, c)
    }

    start := time.Now()
    for i := 0; i < docNum; i++ {
        c <- "ok"
    }
    fmt.Printf("%.2fs total\n", time.Since(start).Seconds())
}

Huge slowdown for request body of length 1025

Previously mentioned in yesodweb/yesod#248 by @luite

I can confirm that this is occurring, but now the weird part: the slowdown seems to be coming from the call to network's recv function. I've added the following debug output to Warp:

, connRecv = do
    time "connRecv start"
    bs <- Sock.recv s bytesPerRead
    time $ "connRecv finish, " ++ show (S.length bs)
    return bs

Plus the helper function time and related imports:

import Data.Time
time s = liftIO $ do
    now <- getCurrentTime
    putStrLn $ show now ++ ": " ++ s

You can see clearly that connRecv finishes about a second after it starts.

Using `vault` from request

I broke my brain when I tried to use vault from Wai.Request. For example, I need middleware for authentification. Current implementation requires that next Application/Middleware in chain received user data as first parameter.

When I try vault. I can store user data with newKey. But how to retrieve it in next Application/Middleware? Can you give an example?

Request port information missing in Request

Hi,

I was trying to write a HTTP proxy using WAI and http-conduit,
but I came across this problem:

Basically, in the HTTP protocol the request port can be different to the host port

for example a client may connect to a HTTP proxy server on
port 8080 and send:

GET http://example.com:3001/index.html HTTP/1.1

In this case, the server port is 8080 but the request
port is 3001. There is currently no way get the
this information in a wai handler.

One possibility, is to add a new field to wai Request

requestPort :: Maybe Int

which is Nothing if there is no explicit requestPort
and Just if the requestPort is specified.

The bigger issue is that not a lot of information
from absolute URI requests is exposed in the API
making it impossible to build proxies with WAI
right now.

Perhaps there should be a field called

absoluteURI :: Maybe URI

for some uri type that would allow proxy
servers to access the absolute URI information.

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.