From 4d7dbe15f9a22ba451c0da2a3d86575e1a195bb1 Mon Sep 17 00:00:00 2001 From: Chuck Ha Date: Wed, 27 Mar 2013 11:06:36 -0400 Subject: [PATCH 1/6] Adds basic Requests library --- Requests/README.md | 13 +++++++++++ Requests/requests.jl | 55 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 68 insertions(+) create mode 100644 Requests/README.md create mode 100644 Requests/requests.jl diff --git a/Requests/README.md b/Requests/README.md new file mode 100644 index 0000000..9a56f55 --- /dev/null +++ b/Requests/README.md @@ -0,0 +1,13 @@ +# Requests + +A human friendly API for sending a request. It's the Julia version of Python [Requests](http://docs.python-requests.org/en/latest/). + +## Usage + +```.jl +# implicit GET +response = request("http://httpbin.org") + +# a broken, but API example +response = request(POST, "http://httpbin.org/post", ["EXTRA" => "HEADERS"], DATA) +``` diff --git a/Requests/requests.jl b/Requests/requests.jl new file mode 100644 index 0000000..0ad9270 --- /dev/null +++ b/Requests/requests.jl @@ -0,0 +1,55 @@ +# A human API for making HTTP Requests +module Requests + +using Httplib + +# Use integers for HTTP methods +const GET = 1 +const POST = 2 +const PUT = 3 +const DELETE = 4 + +# Integers to Strings for HTTP Methods +_method_dict = Dict{Int,String}() +_method_dict[1] = "GET" +_method_dict[2] = "POST" +_method_dict[3] = "PUT" +_method_dict[4] = "DELETE" + +typealias Headers Dict{String, String} +# Represent Headers the way a server would expect them (\r\n) and end with \r\n\r\n +repr(h::Headers) = string(join(["$k: $v" for (k, v) in h], "\r\n"), "\r\n") +add_header{T <: String}(h::Headers, key::T, value::T) = h[key] = value + +repr(r::Request) = string("$(r.method) / HTTP/1.1\r\n", "Host: $(r.resource)\r\n", repr(r.headers), "\r\n") + +# Make an HTTP request and get the response. +# +# # An implicit GET request +# request("http://google.com") +# # FIXME +# request("http://duckduckgo.com", ["q" => "dogs"]) +# # FIXME +# request(POST, "http://httpbin.org/post", ["data" => "some data"]) +# +request{T <: String}(uri::T) = request(GET, uri, Dict{T, T}()) +request{T <: String}(uri::T, data::Dict{T, T}) = request(GET, uri, data) +function request{T <: String}(method::Int, uri::T, data::Dict{T, T}) + client = connect(TcpSocket(), uri, 80)[1] + req = Request(_method_dict[method], uri, default_headers(), "", Dict{T, T}()) + merge!(req.headers, data) + write(client, repr(req)) + readall(client) +end + +default_user_agent() = "julia-requests/0.1 julia/$VERSION" +# Set the default headers for a request +function default_headers() + h = Headers() + add_header(h, "User-Agent", default_user_agent()) + add_header(h, "Accept-Encoding", "gzip, deflate, compress") + add_header(h, "Accept", "*/*") + h +end + +end # end module From cea1bde75e264fb5bcf2121703427254e0b114c7 Mon Sep 17 00:00:00 2001 From: Chuck Ha Date: Wed, 27 Mar 2013 11:55:36 -0400 Subject: [PATCH 2/6] Export the working methods and request function --- Requests/requests.jl | 15 +++------------ 1 file changed, 3 insertions(+), 12 deletions(-) diff --git a/Requests/requests.jl b/Requests/requests.jl index 0ad9270..9663755 100644 --- a/Requests/requests.jl +++ b/Requests/requests.jl @@ -3,18 +3,9 @@ module Requests using Httplib -# Use integers for HTTP methods -const GET = 1 -const POST = 2 -const PUT = 3 -const DELETE = 4 - -# Integers to Strings for HTTP Methods -_method_dict = Dict{Int,String}() -_method_dict[1] = "GET" -_method_dict[2] = "POST" -_method_dict[3] = "PUT" -_method_dict[4] = "DELETE" +# Export the working bits +export GET, + request typealias Headers Dict{String, String} # Represent Headers the way a server would expect them (\r\n) and end with \r\n\r\n From 45dd986957c7f7d8ddc7dde10340741a1b45ba4d Mon Sep 17 00:00:00 2001 From: Chuck Ha Date: Wed, 27 Mar 2013 11:55:59 -0400 Subject: [PATCH 3/6] Reorder request function to be julian --- Requests/requests.jl | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Requests/requests.jl b/Requests/requests.jl index 9663755..f30987a 100644 --- a/Requests/requests.jl +++ b/Requests/requests.jl @@ -23,15 +23,15 @@ repr(r::Request) = string("$(r.method) / HTTP/1.1\r\n", "Host: $(r.resource)\r\n # # FIXME # request(POST, "http://httpbin.org/post", ["data" => "some data"]) # -request{T <: String}(uri::T) = request(GET, uri, Dict{T, T}()) -request{T <: String}(uri::T, data::Dict{T, T}) = request(GET, uri, data) -function request{T <: String}(method::Int, uri::T, data::Dict{T, T}) +function request{T <: String}(method::HttpMethodBitmask, uri::T, data::Dict{T, T}) client = connect(TcpSocket(), uri, 80)[1] - req = Request(_method_dict[method], uri, default_headers(), "", Dict{T, T}()) + req = Request(HttpMethodBitmaskToName(method), uri, default_headers(), "", Dict{T, T}()) merge!(req.headers, data) write(client, repr(req)) readall(client) end +request{T <: String}(uri::T, data::Dict{T, T}) = request(GET, uri, data) +request{T <: String}(uri::T) = request(GET, uri, Dict{T, T}()) default_user_agent() = "julia-requests/0.1 julia/$VERSION" # Set the default headers for a request From d8870373eb49e2709b5c2a520c5cce0eb01021c8 Mon Sep 17 00:00:00 2001 From: Chuck Ha Date: Wed, 27 Mar 2013 12:00:12 -0400 Subject: [PATCH 4/6] Removes redundant typealias --- Requests/requests.jl | 1 - 1 file changed, 1 deletion(-) diff --git a/Requests/requests.jl b/Requests/requests.jl index f30987a..445a81a 100644 --- a/Requests/requests.jl +++ b/Requests/requests.jl @@ -7,7 +7,6 @@ using Httplib export GET, request -typealias Headers Dict{String, String} # Represent Headers the way a server would expect them (\r\n) and end with \r\n\r\n repr(h::Headers) = string(join(["$k: $v" for (k, v) in h], "\r\n"), "\r\n") add_header{T <: String}(h::Headers, key::T, value::T) = h[key] = value From 2477206e4db7f8f922ed17f9f16cc07a1a7c52bb Mon Sep 17 00:00:00 2001 From: Chuck Ha Date: Wed, 27 Mar 2013 13:08:24 -0400 Subject: [PATCH 5/6] Proper Julian layout --- Requests/{requests.jl => src/Requests.jl} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename Requests/{requests.jl => src/Requests.jl} (100%) diff --git a/Requests/requests.jl b/Requests/src/Requests.jl similarity index 100% rename from Requests/requests.jl rename to Requests/src/Requests.jl From 353ec4888ec76cccf48ea9a170d79c939db65b06 Mon Sep 17 00:00:00 2001 From: Chuck Ha Date: Wed, 27 Mar 2013 13:19:55 -0400 Subject: [PATCH 6/6] Dictionary lookup vs method call --- Requests/src/Requests.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Requests/src/Requests.jl b/Requests/src/Requests.jl index 445a81a..38b3704 100644 --- a/Requests/src/Requests.jl +++ b/Requests/src/Requests.jl @@ -24,7 +24,7 @@ repr(r::Request) = string("$(r.method) / HTTP/1.1\r\n", "Host: $(r.resource)\r\n # function request{T <: String}(method::HttpMethodBitmask, uri::T, data::Dict{T, T}) client = connect(TcpSocket(), uri, 80)[1] - req = Request(HttpMethodBitmaskToName(method), uri, default_headers(), "", Dict{T, T}()) + req = Request(HttpMethodBitmaskToName[method], uri, default_headers(), "", Dict{T, T}()) merge!(req.headers, data) write(client, repr(req)) readall(client)