Permalink
Browse files

Initial commit

  • Loading branch information...
oscarh committed Jun 6, 2009
0 parents commit b8f2f937b9fd3635dac56bfd01cc245eac02fefd
Showing with 1,113 additions and 0 deletions.
  1. +15 −0 .hgignore
  2. +23 −0 LICENCE
  3. +48 −0 Makefile
  4. +6 −0 README
  5. +5 −0 doc/overview.edoc
  6. +39 −0 src/lhttpc.app.src
  7. +126 −0 src/lhttpc.erl
  8. +211 −0 src/lhttpc_client.erl
  9. +173 −0 src/lhttpc_lib.erl
  10. +222 −0 src/lhttpc_manager.erl
  11. +159 −0 src/lhttpc_sock.erl
  12. +57 −0 src/lhttpc_sup.erl
  13. +28 −0 src/lhttpc_types.hrl
  14. +1 −0 vsn.mk
@@ -0,0 +1,15 @@
+syntax: glob
+
+
+.args
+.depend
+
+*.sw{p,o}
+
+erl_crash.dump
+
+ebin/{*.beam,lhttpc.app}
+test/*.beam
+doc/{edoc-info,*.{png,css,html}}
+cover_report/*
+
23 LICENCE
@@ -0,0 +1,23 @@
+Copyright (c) 2009, Erlang Training and Consulting Ltd.
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+ * Neither the name of Erlang Training and Consulting Ltd. nor the
+ names of its contributors may be used to endorse or promote products
+ derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY Erlang Training and Consulting Ltd. ''AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL Erlang Training and Consulting Ltd. BE
+LIABLE SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
@@ -0,0 +1,48 @@
+
+
+APPLICATION := lhttpc
+APP_FILE:=ebin/$(APPLICATION).app
+SOURCES:=$(wildcard src/*.erl)
+HEADERS:=$(wildcard src/*.hrl)
+MODULES:=$(patsubst src/%.erl,%,$(SOURCES))
+BEAMS:=$(patsubst %,ebin/%.beam,$(MODULES))
+
+comma := ,
+e :=
+space := $(e) $(e)
+MODULELIST := $(subst $(space),$(comma),$(MODULES))
+
+
+include vsn.mk
+
+.PHONY: all clean dialyzer
+
+all: $(APPLICATION) doc
+
+$(APPLICATION): $(BEAMS) $(APP_FILE)
+
+$(APP_FILE): src/$(APPLICATION).app.src
+ @echo Generating $@
+ @sed -e 's/@MODULES@/$(MODULELIST)/' -e 's/@VSN@/$(VSN)/' $< > $@
+
+ebin/%.beam: src/%.erl $(HEADERS) $(filter-out $(wildcard ebin), ebin)
+ @echo Compiling $<
+ @erlc -o ebin/ $<
+
+ebin:
+ @echo Creating ebin/
+ @mkdir ebin/
+
+doc: doc/edoc-info
+
+dialyzer:
+ @echo Running dialyzer on sources
+ @dialyzer --src -r src/
+
+doc/edoc-info: doc/overview.edoc $(SOURCES)
+ @echo Generating documentation from edoc
+ @erl -noinput -eval 'edoc:application(gen_httpd, "./", [{doc, "doc/"}])' -s erlang halt
+
+clean:
+ @echo Cleaning
+ @rm -f ebin/*.{beam,app} doc/*.{html,css,png} doc/edoc-info
6 README
@@ -0,0 +1,6 @@
+Dependencies:
+* Erlang/OTP R12-B or newer (compiler to build, kernel and stdlib to run)
+* GNU Make (might actually build with some other make as well)
+
+To bulid the application simply run 'make'. This should build .beam, .app
+files and documentation.
@@ -0,0 +1,5 @@
+@author Oscar Hellström <oscar@erlang-consulting.com>
+@doc A lightweight HTTP client.
+The only functions of much interest right now are {@link
+lhttpc:request/4} and {@link lhttpc:request/5}.
+@end
@@ -0,0 +1,39 @@
+%%% ----------------------------------------------------------------------------
+%%% Copyright (c) 2009, Erlang Training and Consulting Ltd.
+%%% All rights reserved.
+%%%
+%%% Redistribution and use in source and binary forms, with or without
+%%% modification, are permitted provided that the following conditions are met:
+%%% * Redistributions of source code must retain the above copyright
+%%% notice, this list of conditions and the following disclaimer.
+%%% * Redistributions in binary form must reproduce the above copyright
+%%% notice, this list of conditions and the following disclaimer in the
+%%% documentation and/or other materials provided with the distribution.
+%%% * Neither the name of Erlang Training and Consulting Ltd. nor the
+%%% names of its contributors may be used to endorse or promote products
+%%% derived from this software without specific prior written permission.
+%%%
+%%% THIS SOFTWARE IS PROVIDED BY Erlang Training and Consulting Ltd. ''AS IS''
+%%% AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+%%% IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+%%% ARE DISCLAIMED. IN NO EVENT SHALL Erlang Training and Consulting Ltd. BE
+%%% LIABLE SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+%%% BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+%%% WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+%%% OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+%%% ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+%%% ----------------------------------------------------------------------------
+
+%%% @author Oscar Hellström <oscar@erlang-consulting.com>
+%%% @doc This is the specification for the lhttpc application.
+%%% @end
+{application, lhttpc,
+ [{description, "Lightweight HTTP Client"},
+ {vsn, "@VSN@"},
+ {modules, [@MODULES@]},
+ {registered, [lhttpc_manager]},
+ {applications, [kernel, stdlib]},
+ {mod, {lhttpc, nil}},
+ {env, []}
+ ]}.
+
@@ -0,0 +1,126 @@
+%%% ----------------------------------------------------------------------------
+%%% Copyright (c) 2009, Erlang Training and Consulting Ltd.
+%%% All rights reserved.
+%%%
+%%% Redistribution and use in source and binary forms, with or without
+%%% modification, are permitted provided that the following conditions are met:
+%%% * Redistributions of source code must retain the above copyright
+%%% notice, this list of conditions and the following disclaimer.
+%%% * Redistributions in binary form must reproduce the above copyright
+%%% notice, this list of conditions and the following disclaimer in the
+%%% documentation and/or other materials provided with the distribution.
+%%% * Neither the name of Erlang Training and Consulting Ltd. nor the
+%%% names of its contributors may be used to endorse or promote products
+%%% derived from this software without specific prior written permission.
+%%%
+%%% THIS SOFTWARE IS PROVIDED BY Erlang Training and Consulting Ltd. ''AS IS''
+%%% AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+%%% IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+%%% ARE DISCLAIMED. IN NO EVENT SHALL Erlang Training and Consulting Ltd. BE
+%%% LIABLE SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+%%% BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+%%% WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+%%% OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+%%% ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+%%% ----------------------------------------------------------------------------
+
+%%% @author Oscar Hellström <oscar@erlang-consulting.com>
+%%% @doc Main interface to the lightweight http client.
+%%% See `request/4' and `request/5' functions.
+%%% @end
+-module(lhttpc).
+-behaviour(application).
+
+-export([request/4, request/5]).
+-export([start/2, stop/1]).
+
+-include("lhttpc_types.hrl").
+
+-type result() :: {ok, {{pos_integer(), string()}, headers(), binary()}} |
+ {error, atom()}.
+
+%% @hidden
+-spec start(normal | {takeover, node()} | {failover, node()}, any()) ->
+ {ok, pid()}.
+start(_, _) ->
+ lhttpc_sup:start_link().
+
+%% @hidden
+-spec stop(any()) -> ok.
+stop(_) ->
+ ok.
+
+%% @spec (URL, Method, Hdrs, Timeout) -> Result
+%% URL = string()
+%% Method = string() | atom()
+%% Hdrs = [{Header, Value}]
+%% Header = string() | binary() | atom()
+%% Value = string() | binary()
+%% Timeout = integer() | infinity
+%% Result = {ok, {{StatusCode, ReasonPhrase}, Hdrs, Body}}
+%% | {error, Reason}
+%% StatusCode = integer()
+%% ReasonPhrase = string()
+%% Body = binary()
+%% @doc Sends a request without a body.
+%% Would be the same as calling `request(URL, Method, Hdrs, [], Timeout)',
+%% that is `request/5' with an empty body (`Body' could also be `<<>>').
+%% @end
+-spec request(string(), string() | atom(), headers(), pos_integer() |
+ infinity) -> result().
+request(URL, Method, Hdrs, Timeout) ->
+ request(URL, Method, Hdrs, [], Timeout).
+
+%% @spec (URL, Method, Hdrs, RequestBody, Timeout) -> Result
+%% URL = string()
+%% Method = string() | atom()
+%% Hdrs = [{Header, Value}]
+%% Header = string() | binary() | atom()
+%% Value = string() | binary()
+%% RequestBody = iolist()
+%% Timeout = integer() | infinity
+%% Result = {ok, {{StatusCode, ReasonPhrase}, Hdrs, ResponseBody}}
+%% | {error, Reason}
+%% StatusCode = integer()
+%% ReasonPhrase = string()
+%% ResponseBody = binary()
+%% @doc Sends a request with a body.
+%% `URL' is expected to be a valid URL:
+%% `scheme://host[:port][/path]'.
+%% `Method' is either a string, stating the HTTP method exactly as in the
+%% protocol, i.e: `"POST"' or `"GET"'. It could also be an atom, which is
+%% then made in to uppercase, if it isn't already.
+%% `Hdrs' is a list of headers to send. Mandatory headers such as
+%% `Host' or `Content-Length' (for some requests) are added.
+%% `Body' is the entity to send in the request. Please don't include entity
+%% bodies where there shouldn't be any (such as for `GET').
+%% `Timeout' is the timeout for the request in milliseconds.
+%% @end
+-spec request(string(), string() | atom(), headers(), iolist(),
+ pos_integer() | infinity) -> result().
+request(URL, Method, Hdrs, Body, Timeout) ->
+ Args = [self(), URL, Method, Hdrs, Body],
+ Pid = spawn_link(lhttpc_client, request, Args),
+ receive
+ {response, Pid, R} ->
+ R;
+ {'EXIT', Pid, Reason} ->
+ % This could happen if the process we're running in taps exits
+ erlang:error(Reason)
+ after Timeout ->
+ kill_client(Pid)
+ end.
+
+kill_client(Pid) ->
+ Monitor = erlang:monitor(process, Pid),
+ unlink(Pid), % or we'll kill ourself :O
+ exit(Pid, timeout),
+ receive
+ {response, Pid, R} ->
+ erlang:demonitor(Monitor, [flush]),
+ R;
+ {'DOWN', _, process, Pid, timeout} ->
+ {error, timeout};
+ {'DOWN', _, process, Pid, Reason} ->
+ erlang:error(Reason)
+ end.
Oops, something went wrong.

0 comments on commit b8f2f93

Please sign in to comment.