land of lisp src webserver.lisp - webdev.webserver

while I was learning in "land of lisp" chapter 12 and 13 about "socket".
I use lispbox, so I need install a socket.At last, I found usocket available.
this is a sample about how to use usocket, to bulid a webserver.
(defun serve (request-handler)
"serve as a web server,used to handle request
like 'http://127.0.0.1:8080/greeting'"
(let ((socket (usocket:socket-listen "0.0.0.0" 8080 :reuse-address t)))
(unwind-protect
(loop (with-open-stream (stream
(usocket:socket-stream
(usocket:socket-accept socket)))
(let* ((url (parse-url (read-line stream)))
(path (car url))
(header (get-header stream))
(params (append (cdr url)
(get-content-params stream header)))
(*standard-output* stream))
(funcall request-handler path header params))))
(usocket:socket-close socket))))
the origin ‘serve’ function in http://landoflisp.com/webserver.lisp
(defun serve (request-handler)
(let ((socket (socket-server 8080)))
(unwind-protect
(loop (with-open-stream (stream (socket-accept socket))
(let* ((url (parse-url (read-line stream)))
(path (car url))
(header (get-header stream))
(params (append (cdr url)
(get-content-params stream header)))
(*standard-output* stream))
(funcall request-handler path header params))))
(socket-server-close socket))))

API definition
usocket (class)
stream-usocket (class; usocket derivative)
stream-server-usocket (class; usocket derivative)
socket-connect (function) [ to create an active/connected socket ]
socket-connect host port &key element-type
where `host' is a vectorized ip
or a string representation of a dotted ip address
or a hostname for lookup in the DNS system
socket-listen (function) [ to create a passive/listening socket ]
socket-listen host port &key reuseaddress backlog element-type
where `host' has the same definition as above
socket-accept (method) [ to create an active/connected socket ]
socket-accept socket &key element-type
returns (server side) a connected socket derived from a
listening/passive socket.
socket-close (method)
socket-close socket
where socket a previously returned socket
socket (usocket slot accessor),
the internal/implementation defined socket representation
socket-stream (usocket slot accessor),
socket-stream socket
the return value of which satisfies the normal stream interface

Related

erlang/elixir parse OCSPResponse (asn.1)

Is there any way to parse OCSP response in erlang/elixir?
Probably I don't understand something, but it is ASN.1 type OCSPResponse fails
:public_key.der_decode(:OCSPResponse,data)
Also I have tried download and compile:
asn1ct:compile("/Users/edenlab/workspace/ocsp_client/ocsp.asn1", [ber, verbose]).
but it fails with a list of errors:
OCSP-2009:8: 'ATTRIBUTE' is not exported from PKIX-CommonTypes-2009
OCSP-2009:8: 'EXTENSION' is not exported from PKIX-CommonTypes-2009
...
OCSP-2009:180: illegal OBJECT IDENTIFIER
OCSP-2009:181: illegal OBJECT IDENTIFIER
{error,[{structured_error,{'OCSP-2009',8},
asn1ct_check,
{undefined_import,'ATTRIBUTE','PKIX-CommonTypes-2009'}},
Is there something like OCSP lib in Ruby?
elixir code
with {:CertificateList, tbs_certs, _, _} <-
:public_key.der_decode(:CertificateList, data),
{:TBSCertList, _, _, _, _, {:utcTime, ts}, certs, _} <- tbs_certs do
...
end

YAWs embedded with appmod not working for me

Alright, what am I doing wrong here. I'm trying the simple example of embedded YAWs from http://yaws.hyber.org/embed.yaws but with an appmod. I've added the my_app.erl file and compiled it. It works if not in embedded YAWs so I think it is specific to embedded.
-module(ybed).
-compile(export_all).
start() ->
{ok, spawn(?MODULE, run, [])}.
run() ->
Id = "embedded",
GconfList = [{ebin_dir, ["/Users/someuser/yawsembedded/ebin"]}],
Docroot = "/Users/someuser/yawstest",
SconfList = [{port, 8888},
{listen, {0,0,0,0}},
{docroot, Docroot},
{appmods, [{"/", my_app}]}
],
{ok, SCList, GC, ChildSpecs} =
yaws_api:embedded_start_conf(Docroot, SconfList, GconfList),
[supervisor:start_child(ybed_sup, Ch) || Ch <- ChildSpecs],
yaws_api:setconf(GC, SCList),
{ok, self()}.
Getting this Error:
ERROR erlang code threw an uncaught exception:
File: appmod:0
Class: error
Exception: undef
Req: {http_request,'GET',{abs_path,"/demo"},{1,1}}
Stack: [{my_app,out,
[{arg,#Port<0.2721>,
{{127,0,0,1},63720},
{headers,"keep-alive",
"text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8",
"0.0.0.0:8888",undefined,undefined,undefined,undefined,
undefined,undefined,undefined,
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10.10; rv:40.0) Gecko/20100101 Firefox/40.0",
undefined,[],undefined,undefined,undefined,undefined,
undefined,undefined,undefined,undefined,
[{http_header,0,"Dnt",undefined,"1"},
{http_header,10,'Accept-Encoding',undefined,
"gzip, deflate"},
{http_header,11,'Accept-Language',undefined,"null"}]},
{http_request,'GET',{abs_path,"/demo"},{1,1}},
{http_request,'GET',{abs_path,"/demo"},{1,1}},
undefined,"/demo",undefined,undefined,
"/Users/someuser/yawstest","/",
"/Users/someuser/yawstest/demo",undefined,undefined,
<0.63.0>,[],"/","/",undefined}],
[]},
{yaws_server,deliver_dyn_part,8,
[{file,"yaws_server.erl"},{line,2818}]},
{yaws_server,aloop,4,[{file,"yaws_server.erl"},{line,1232}]},
{yaws_server,acceptor0,2,[{file,"yaws_server.erl"},{line,1068}]},
{proc_lib,init_p_do_apply,3,[{file,"proc_lib.erl"},{line,239}]}]
The stack trace shows that your my_app:out/1 function is getting called, but you're getting an undef exception. This is occurring because the runtime can't find the my_app:out/1 function, which means either it can't find the module or the module exists but does not export an out/1 function. For example, I was able to duplicate the error using the example code by not providing a my_app module.
First, make sure your my_app.erl file exports an out/1 function. Here's a trivial one that just returns a 405 error for all requests:
-module(my_app).
-export([out/1]).
out(_Arg) ->
{status, 405}.
Compile your my_app.erl file and put the compiled my_app.beam file either in a load path already known to the Erlang runtime, or in a directory you add to the load path. In your code it appears you're trying the latter approach, since you're specifically adding an ebin_dir with this Yaws global configuration directive:
GconfList = [{ebin_dir, ["/Users/someuser/yawsembedded/ebin"]}],
You need to verify that the /Users/someuser/yawsembedded/ebin directory exists, and that the compiled my_app.beam file is located there.

F# R Provider: Method not found: 'RDotNet.REngine RDotNet.REngine.GetInstance

I am using the R Type Provider like so in the REPL
#r "../packages/FSharp.Data.2.2.0/lib/net40/FSharp.Data.dll"
open FSharp.Data
[<Literal>]
let uri = "https://reddoggabtest-secondary.table.core.windows.net/TestTelemetryData0?tn=TestTelemetryData0&sv=2014-02-14&si=GabLab&sig=GGc%2BHEa9wJYDoOGNE3BhaAeduVOA4MH8Pgss5kWEIW4%3D"
type CarTelemetry = XmlProvider<uri>
let carTelemetry = CarTelemetry.Load(uri)
#r "C:/Program Files (x86)/Reference Assemblies/Microsoft/Framework/.NETFramework/v4.5.1/System.Xml.Linq.dll"
open System.Xml.Linq
carTelemetry.Entries |> Seq.iter(fun e -> printfn "%A" e.Title)
#I "../packages/RProvider.1.1.8/lib"
#r "../packages/R.NET.1.5.5/lib/net40/RDotNet.dll"
#r "../packages/R.NET.1.5.5/lib/net40/RDotNet.NativeLibrary.dll"
#r "../packages/R.NET.Community.FSharp.0.1.9/lib/net40/RDotNet.FSharp.dll"
#r "../packages/RProvider.1.1.8/lib/net40/RProvider.dll"
#r "../packages/RProvider.1.1.8/lib/net40/RProvider.Runtime.dll"
open System
open System.Net
open RDotNet
open RProvider
open RProvider.graphics
open RProvider.stats
carTelemetry.Entries |> Seq.map(fun e -> e.Content.Properties.Acceleration.Value)
|> R.log
|> R.diff
When I execute it, I am getting this exception
System.MissingMethodException: Method not found: 'RDotNet.REngine RDotNet.REngine.GetInstance(System.String, Boolean, RDotNet.StartupParameter, RDotNet.Devices.ICharacterDevice)'.
at RProvider.Internal.RInit.engine#114.Invoke()
at System.Lazy`1.CreateValue()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Lazy`1.get_Value()
at RProvider.RInteropInternal.toR(Object value) in c:\Tomas\Public\FSharp.RProvider\src\RProvider\RInterop.fs:line 287
at RProvider.RInterop.passArg#447(List`1 tempSymbols, Object arg) in c:\Tomas\Public\FSharp.RProvider\src\RProvider\RInterop.fs:line 461
at RProvider.RInterop.argList#468-1.GenerateNext(IEnumerable`1& next) in c:\Tomas\Public\FSharp.RProvider\src\RProvider\RInterop.fs:line 475
at Microsoft.FSharp.Core.CompilerServices.GeneratedSequenceBase`1.MoveNextImpl()
at Microsoft.FSharp.Core.CompilerServices.GeneratedSequenceBase`1.System-Collections-IEnumerator-MoveNext()
at Microsoft.FSharp.Collections.SeqModule.ToArray[T](IEnumerable`1 source)
at RProvider.RInterop.callFunc(String packageName, String funcName, IEnumerable`1 argsByName, Object[] varArgs) in c:\Tomas\Public\FSharp.RProvider\src\RProvider\RInterop.fs:line 466
at <StartupCode$FSI_0012>.$FSI_0012.main#()
Stopped due to error
Any ideas? Thanks.
This looks like some version mismatch - what version(s) of R.NET do you have installed in the packages folder?
The correct ones (as required by the latest R provider NuGet package) are:
R.NET.Community (= 1.5.16)
R.NET.Community.FSharp (= 0.1.9)
Note that there is (confusingly) also older R.NET package (without the "Community" bit) and having that in packages can probably confuse the R provider.
BTW: You can also try using the FsLab templates instead, which makes the process of installing & loading everything a lot simpler - reduces all to just a single #load :-)

cowboy connection process terminated with enomem

I encountered an cowboy error
Ranch listener api_resource had connection process started with cowboy_protocol:start_link/4 at <0.1822.0> exit with reason: enomem#012
In the request handler, I'm interacting with another vendor's tts platform, via erlang port(c language). The first tts command to the port succeeded, I can got 1M bytes data, the second tts command to the port is sent to the port successfully, but then the cowboy process terminated immediatedly with the error message above.
I've tried to raise erlang vm's stack size, heap size, binary virtual heap size, and os's stack size, no help.
Any suggestion is appreciated, thanks.
code:
tts(Port, Params, Text) ->
case call_port(Port, {'set_tts_params', Params}) of
{'error', _}=Error -> Error;
_ -> slice_tts(Port, slice_text(Text), <<>>)
end.
slice_tts(_Port, [], Acc) ->
lager:debug("tts over"),
{'ok', <<"RIFF", (byte_size(Acc)+36):32, "WAVE", "fmt ", 16:32,
1:16, 1:16, 16000:32, 32000:32, 2:16, 16:16,
"data", (byte_size(Acc)):32, Acc/binary>>};
slice_tts(Port, [Text|Others], Acc) ->
lager:debug("ttsing ~p bytes", [byte_size(Text)]),
case call_port(Port, {'tts', Text}) of
{'error', _}=Error -> Error;
{'ok', Data} -> slice_tts(Port, Others, <<Acc/binary, Data/binary>>)
end.

Using elcloud_s3 to upload to files to S3 i

I am trying to use the erlang module erlcloud_s3 to upload a file to S3. For some reason that I have not been able to work out it does not work. I have included my code (with keys removed of course) and the response that I get when I try to run this. Can someone tell me what I am missing (or if there is a better AWS package for Erlang that actually has some docs or examples?)
-module(compose).
-define('ACCESS_KEY', "********************").
-define('SECRET_ACCESS_KEY', "****************************************").
-define('BUCKET', "zacharykessin").
-export([upload/2, upload_file/2]).
upload_file(Key, Path) ->
R = file:read_file(Path),
{ok, Binary} = R,
upload(Key, Binary).
upload(Key, Value) ->
A = erlcloud_ec2:configure(?ACCESS_KEY, ?SECRET_ACCESS_KEY),
error_logger:info_msg("~p:~p Settng up AWS ~p to S3 ~n",
[?MODULE, ?LINE, A]),
R = erlcloud_s3:put_object(?BUCKET, Key, Value, [], [{"Content-type", "image/jpeg"}]),
error_logger:info_msg("~p:~p Uploaded File ~p to S3 ~n",
[?MODULE, ?LINE, R]),
{ok, R}.
{noproc,
{gen_server,call,
[httpc_manager,
{request,
{request,undefined,<0.2.0>,0,https,
{"zacharykessin.s3.amazonaws.com",443},
"/test",[],put,
{http_request_h,undefined,"keep-alive",
"Thu, 15 Mar 2012 14:22:14 GMT",
undefined,undefined,undefined,undefined,
undefined,undefined,undefined,undefined,
undefined,undefined,
["AWS ","********************",58,
<<"1O6HYjq8RU8sqtD8oZd1T+bMNCE=">>],
undefined,undefined,
"zacharykessin.s3.amazonaws.com",
undefined,undefined,undefined,undefined,
undefined,undefined,undefined,undefined,
undefined,[],undefined,undefined,...},
{"application/octet_stream",
<<255,216,255,224,0,16,74,70,73,70,0,1,2,1,
1,44,1,44,0,0,255,225,25,59,69,120,105,...>>},
{http_options,"HTTP/1.1",infinity,true,
{essl,[]},
undefined,false,infinity,false},
"https://zacharykessin.s3.amazonaws.com/test",
[],none,[],1331821334636,undefined,undefined,
false}},
infinity]}}
Make sure to run
inets:start()
somewhere before running your code.
The error you are getting means that there is no such process (noproc) registered as httpc_manager, which is a part of inets library application.

Resources