Git Product home page Git Product logo

http-easy's Introduction

Actions Status

NAME

HTTP::Easy - HTTP servers made easy, including PSGI

SYNOPSIS

use HTTP::Easy;

DESCRIPTION

Raku libraries to make HTTP servers easily.

This was inspired by HTTP::Server::Simple, but has a very different internal API, and extended functionality. It's been designed to work well with the Web::App and SCGI libraries.

HTTP::Easy

A role to build HTTP daemon classes with. This provides the framework for parsing HTTP connections.

HTTP::Easy::PSGI

A class consuming the HTTP::Easy role. This builds a PSGI environment, and passes it onto a handler. The handler must return a PSGI response:

[ $status, @headers, @body ]

This can be used as an engine in the Web::App library.

Example

use HTTP::Easy::PSGI;
my $http = HTTP::Easy::PSGI.new(:port(8080));

my $app = sub (%env) {
    my $name = %env<QUERY_STRING> || "World";
    [ 200, [ 'Content-Type' => 'text/plain' ], [ "Hello $name" ] ]
}

$http.handle($app);

TODO

Implement HTTP/1.1 features such as Transfer-Encoding, etc.

AUTHOR

Timothy Totten

COPYRIGHT AND LICENSE

Copyright 2011 - 2017 Timothy Totten

Copyright 2018 - 2022 Raku Community

This library is free software; you can redistribute it and/or modify it under the Artistic License 2.0.

http-easy's People

Contributors

azawawi avatar curttilmes avatar gerdr avatar hiroraba avatar jj avatar jsimonet-caldera avatar lizmat avatar mattn avatar pnu avatar stmuk avatar supernovus avatar szabgab avatar teodozjan avatar timo avatar ufobat avatar zoffixznet avatar zostay avatar

Stargazers

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

Watchers

 avatar  avatar  avatar  avatar  avatar

http-easy's Issues

Invalid operation on binary string

I was writing blogpost about RPC communication in Perl6 and I've noticed that on latest Rakudo Star 2012.12 HTTP::Easy breaks with following error:

$ perl6 librarian.pl 
[2013-01-03T23:01:52Z] Started HTTP server.
[2013-01-03T23:02:22Z] POST / HTTP/1.1
Invalid operation on binary string
  in method uc at src/gen/CORE.setting:2206
  in method dispatch:<.=> at src/gen/CORE.setting:945
  in block  at /Users/bbkr/Developer/Perl6/rakudo/install/lib/parrot/4.10.0/languages/perl6/lib/HTTP/Easy.pm6:93
  in method reify at src/gen/CORE.setting:5495
  in method reify at src/gen/CORE.setting:5397
  in method reify at src/gen/CORE.setting:5397
  in method gimme at src/gen/CORE.setting:5775
  in method eager at src/gen/CORE.setting:5754
  in method eager at src/gen/CORE.setting:1189
  in sub eager at src/gen/CORE.setting:6052
  in method run at /Users/bbkr/Developer/Perl6/rakudo/install/lib/parrot/4.10.0/languages/perl6/lib/HTTP/Easy.pm6:88
  in method run at /Users/bbkr/Developer/Perl6/rakudo/install/lib/parrot/4.10.0/languages/perl6/lib/JSON/RPC/Server.pm:40
  in block  at librarian.pl:39

To reproduce one can run librarian.pl and then client.pl from article link above.

It was working fine with 2012.11 release. I'm not sure if broken IO::Socket.read(?) method is related to this issue.

Apache benchmark fails

All tools like wget or Perl5 LWP works fine with HTTP::Easy, except Apache benchmark.

bbkr$ ab http://localhost:8080/
This is ApacheBench, Version 2.3 <$Revision: 655654 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/

Benchmarking localhost (be patient)...apr_socket_recv: Connection refused (61)

Default server ran from test/test.p6. Log shows no request, even in :debug mode.

doesn't die if port is already bound

perl6 -e 'use HTTP::Easy::PSGI; HTTP::Easy::PSGI.new(:port(5000)).handle(sub (%e) { });'
if something is already listening on port 5000, it will print:
[2015-07-15T06:48:11Z] Started HTTP server.
but of course it won't get any requests
Note: It properly dies if trying to bind a low port and no privileges

Closing connection without returning any data back / POSTDATA questions.

I'm trying to replace HTTP transport in my JSON::RPC module with HTTP::Easy, to do so I need to resolve two issues:

  • JSON RPC has something called notification - server should accept and process request and close connection without sending any data back (sending HTTP 200 with empty body is _not_ the same). Can I force this behavior in HTTP::Easy? I tried to return nothing from $app method but it just crashes whole server with
use of uninitialized value of type Any in string context  in method handler at /home/ppabian/rakudo/install/lib/parrot/4.6.0/languages/perl6/lib/HTTP/Easy/PSGI.pm6:40

error.

  • Where can I get raw Content from?

I found that in HTTP::Easy content is available in "psgi.input" env key. Is it something that I can rely on or it may change in the future into something like POSTDATA (like the one described in P5 CGI POD )?

panda installation error...

azawawi@ubuntu:~/perl6-http-easy$ panda install HTTP::Easy
==> Fetching HTTP::Easy
==> Building HTTP::Easy
Compiling lib/HTTP/Easy.pm6
===SORRY!===
Variable $str is not declared
at lib/HTTP/Easy.pm6:139
Mu()
build stage failed for HTTP::Easy: Failed building lib/HTTP/Easy.pm6
in block at /home/azawawi/rakudo-star-2012.09/install/lib/parrot/4.6.0/languages/perl6/lib/Panda/Builder.pm:53
in sub withp6lib at /home/azawawi/rakudo-star-2012.09/install/lib/parrot/4.6.0/languages/perl6/lib/Panda/Common.pm:31
in method build at /home/azawawi/rakudo-star-2012.09/install/lib/parrot/4.6.0/languages/perl6/lib/Panda/Builder.pm:45
in method build-helper at /home/azawawi/rakudo-star-2012.09/install/lib/parrot/4.6.0/languages/perl6/lib/Pies.pm:50
in method resolve-helper at /home/azawawi/rakudo-star-2012.09/install/lib/parrot/4.6.0/languages/perl6/lib/Pies.pm:85
in method resolve at /home/azawawi/rakudo-star-2012.09/install/lib/parrot/4.6.0/languages/perl6/lib/Pies.pm:98
in any call_with_capture at src/gen/Metamodel.pm:2765
in block at src/gen/CORE.setting:489
in method resolve at /home/azawawi/rakudo-star-2012.09/install/lib/parrot/4.6.0/languages/perl6/lib/Panda.pm:84
in block at /home/azawawi/rakudo-star-2012.09/install/bin/panda:113
in method reify at src/gen/CORE.setting:5262
in method reify at src/gen/CORE.setting:5164
in method reify at src/gen/CORE.setting:5164
in method gimme at src/gen/CORE.setting:5542
in method eager at src/gen/CORE.setting:5521
in method eager at src/gen/CORE.setting:1140
in sub eager at src/gen/CORE.setting:5820
in sub MAIN at /home/azawawi/rakudo-star-2012.09/install/bin/panda:110
in block at /home/azawawi/rakudo-star-2012.09/install/bin/panda:106

recv() is not guaranteed to work the way it is used in this module

Problem

Handler may get random $.body content from following P5 client code.

use IO::Socket;
my $sock = IO::Socket::INET->new(PeerAddr=>"localhost",PeerPort=>8080,Proto=>"tcp") or die;
print $sock "POST / HTTP/1.0\\r\nContent-Length: 5r\n\r\n";
print $sock "Hello" ;

Sometimes $.body will be present, sometimes not - depending on race condition between client sending to socket and HTTP::Easy consuming from it. If recv() consumed headers before client send body then recv() won't see body and fetch it.

Try this on laggy network or put "sleep 1" before "Hello" is passed,

Solution

Decompose request fetch

  • socket.get() status line
  • socket.get() headers, parse them on-the fly, stop on empty line
  • how many bytes are left? easy to tell

RFC HTTP 1.0 says

The presence of an entity body in a
request is signaled by the inclusion of a Content-Length header field
in the request message headers. HTTP/1.0 requests containing an
entity body must include a valid Content-Length header field.

So easy deal here, just socket.read( $content_length ).decode() octets.

RFC HTTP 1.1 says

For compatibility with HTTP/1.0 applications, HTTP/1.1 requests containing
a message-body MUST include a valid Content-Length header field
unless the server is known to be HTTP/1.1 compliant.

And this one gets ugly in one case because

 If a message is received with both a
 Transfer-Encoding header field and a Content-Length header field,
 the latter MUST be ignored.

Since implementing 1.1 toys such as chunked Transfer-Encoding is way beyond reasonable time I would suggest just to socket.recv in this ugly case (it won't be worse than it is now). In other cases precise amount of octets can be received as in HTTP 1.0.

Use of uninitialized value of type Any in numeric context

Use of uninitialized value of type Any in numeric context
in block at /root/.rakudobrew/moar-nom/install/share/perl6/site/sources/100A1B43D02574570A9FA5
343A0679EF35FBD229 (HTTP::Easy) line 101
Will not decode invalid ASCII (code point > 127 found)
in method run at /root/.rakudobrew/moar-nom/install/share/perl6/site/sources/100A1B43D02574570A
9FA5343A0679EF35FBD229 (HTTP::Easy) line 103
in sub baile at /root/.rakudobrew/moar-nom/install/share/perl6/site/sources/D57520A5A045A33D405
E36DAA759641E90C1FD99 (Bailador) line 95
in block at app.pm6 line 30

No such method 'decode' for invocant of type 'Any'

Quite oftens exits with the following information:

[2014-11-24T21:50:42Z] GET / HTTP/1.1
use of uninitialized value of type Any in numeric context  in method run at /home/vti/dev/perl6/rakudo-star-2014.09/install/languages/perl6/lib/HTTP/Easy.pm6:71

No such method 'decode' for invocant of type 'Any'
  in method run at /home/vti/dev/perl6/rakudo-star-2014.09/install/languages/perl6/lib/HTTP/Easy.pm6:74
  in method handle at /home/vti/dev/perl6/rakudo-star-2014.09/install/languages/perl6/lib/HTTP/Easy/PSGI.pm6:51
  in block <unit> at app.pl6:56

I guess sometimes recv doesn't return anything.

POST with file uploads is broken

Not sure how long this has been broken, but yeah, if you try to use a multipart/form-data POST with a file attachment, stuff breaks, badly.

Server stalled

I am using example form readme in http.pl. It stalls. I am using rakudo 2013.02.01. I think the same problem is manifested in Bailador.

perl6 http.pl
[2013-02-28T16:44:41Z] Started HTTP server.
[2013-02-28T16:44:42Z] Client connection received.
[2013-02-28T16:44:42Z] GET / HTTP/1.1
Host: localhost:8080
Connection: keep-alive
Cache-Control: max-age=0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,/;q=0.8
User-Agent: Mozilla/5.0 (Macintosh; Inte. l Mac OS X 10_8_2) AppleWebKit/537.22 (KHTML, like Gecko) Chrome/25.0.1364.99 Safari/537.22
Accept-Encoding: gzip,deflate,sdch
Accept-Language: en-US,en;q=0.8
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.3
Cookie: remember_user_token=BAhbB1sGaQZJIiIkMmEkMTAkOEFlRHpVbkhlRGMuSEo5TU9nOVNaLgY6BkVU--115f241404a6c3d4bbfdd1a4fed7a1873ea54ae2; remember_korisnik_token=BAhbB1sGaQZJIhlSelY5ODFhenJoOXN5eE5QeGl6WQY6BkVG--b7c4594a3f8eb77d1579789982a20c28fc48e168

Example does not work

Similar problem to the one with Fast::CGI

$ perl6 test.p6 
Nothing given for new socket to connect or bind to. Invalid arguments to .new?
  in method connect at /home/jmerelo/.rakudobrew/moar-2017.11/install/share/perl6/site/sources/100A1B43D02574570A9FA5343A0679EF35FBD229 (HTTP::Easy) line 33
  in method run at /home/jmerelo/.rakudobrew/moar-2017.11/install/share/perl6/site/sources/100A1B43D02574570A9FA5343A0679EF35FBD229 (HTTP::Easy) line 49
  in block <unit> at test.p6 line 17

Tests might help to catch this, as indicated in #13

No tests

This module is included in Rakudo * - the lack of tests make it very hard to insure we haven't broken anything in a new Star release.

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.