Skip to content

Commit

Permalink
upgrade GitHub to use newest HTTP (#102)
Browse files Browse the repository at this point in the history
* upgrade GitHub to use newest HTTP

* use HTTP.listen instead of HTTP.Servers.serve

* small fixups

* fixes for 0.7

* remove unnecessery declaration

* Update REQUIRE

* Update REQUIRE
  • Loading branch information
KristofferC authored Jan 29, 2018
1 parent 38eb5f9 commit 33e3dd4
Show file tree
Hide file tree
Showing 19 changed files with 68 additions and 79 deletions.
16 changes: 8 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,8 @@ Here's a table that matches up the provided `GitHubType`s with their correspondi
|---------------|--------------------------------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `Owner` | login, e.g. `"octocat"` | [organizations](https://developer.github.com/v3/orgs/), [users](https://developer.github.com/v3/users/) |
| `Repo` | full_name, e.g. `"JuliaWeb/GitHub.jl"` | [repositories](https://developer.github.com/v3/repos/) |
| `Commit` | sha, e.g. `"d069993b320c57b2ba27336406f6ec3a9ae39375"` | [repository commits](https://developer.github.com/v3/repos/commits/) |
| `GitCommit` | sha, e.g. `"d069993b320c57b2ba27336406f6ec3a9ae39375"` | [raw git commits](https://developer.github.com/v3/git/commits/) |
| `Commit` | sha, e.g. `"d069993b320c57b2ba27336406f6ec3a9ae39375"` | [repository commits](https://developer.github.com/v3/repos/commits/) |
| `GitCommit` | sha, e.g. `"d069993b320c57b2ba27336406f6ec3a9ae39375"` | [raw git commits](https://developer.github.com/v3/git/commits/) |
| `Branch` | name, e.g. `master` | [repository branches](https://developer.github.com/v3/repos/#get-branch) |
| `Content` | path, e.g. `"src/owners/owners.jl"` | [repository contents](https://developer.github.com/v3/repos/contents/) |
| `Comment` | id, e.g. `162224613` | [commit comments](https://developer.github.com/v3/repos/comments/), [issue comments](https://developer.github.com/v3/issues/comments/), [PR review comments](https://developer.github.com/v3/pulls/comments/) |
Expand All @@ -54,11 +54,11 @@ Here's a table that matches up the provided `GitHubType`s with their correspondi
| `Issue` | number, e.g. `31` | [issues](https://developer.github.com/v3/issues/) |
| `Team` | id, e.g. `1` | [teams](https://developer.github.com/v3/orgs/teams) |
| `Gist` | id, e.g. `0bace7cc774df4b3a4b0ee9aaa271ef6` | [gists](https://developer.github.com/v3/gists) |
| `Review` | id, e.g. `1` | [reviews](https://developer.github.com/v3/pulls/reviews/) |
| `Blob` | sha, e.g. `"95c8d1aa2a7b1e6d672e15b67e0df4abbe57dcbe"` | [raw git blobs](https://developer.github.com/v3/git/blobs/)
| `Tree` | sha, e.g. `"78e524d5e979e326a7c144ce195bf94ca9b04fa0"` | [raw git trees](https://developer.github.com/v3/git/trees/)
| `Tag` | tag name, e.g. `v1.0` | [git tags](https://developer.github.com/v3/git/tags/)
| `References` | reference name, e.g. `heads/master` (note: omits leading `refs/`) | [git tags](https://developer.github.com/v3/git/refs/)
| `Review` | id, e.g. `1` | [reviews](https://developer.github.com/v3/pulls/reviews/) |
| `Blob` | sha, e.g. `"95c8d1aa2a7b1e6d672e15b67e0df4abbe57dcbe"` | [raw git blobs](https://developer.github.com/v3/git/blobs/) |
| `Tree` | sha, e.g. `"78e524d5e979e326a7c144ce195bf94ca9b04fa0"` | [raw git trees](https://developer.github.com/v3/git/trees/) |
| `Tag` | tag name, e.g. `v1.0` | [git tags](https://developer.github.com/v3/git/tags/) |
| `References` | reference name, e.g. `heads/master` (note: omits leading `refs/`) | [git tags](https://developer.github.com/v3/git/refs/) |


You can inspect which fields are available for a type `G<:GitHubType` by calling `fieldnames(G)`.
Expand Down Expand Up @@ -89,7 +89,7 @@ GitHub.jl implements a bunch of methods that make REST requests to GitHub's API.

| method | return type | documentation |
|------------------------------------------|------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `repo(repo)` | `Repo` | [get `repo`](https://developer.github.com/v3/repos/#get) |
| `repo(repo)` | `Repo` | [get `repo`](https://developer.github.com/v3/repos/#get) |
| `create_repo(owner, name, params=Dict{String,String}())` | `Repo` | [create a repository of the given `name` in the given `owner`'s account](https://developer.github.com/v3/repos/#create) |
| `create_fork(repo)` | `Repo` | [create a fork of `repo`](https://developer.github.com/v3/repos/forks/#create-a-fork) |
| `forks(repo)` | `Tuple{Vector{Repo}, Dict}` | [get `repo`'s forks](https://developer.github.com/v3/repos/forks/#list-forks) |
Expand Down
6 changes: 4 additions & 2 deletions REQUIRE
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
julia 0.6

Compat 0.43
JSON
MbedTLS
HTTP 0.5.4
HttpCommon # for deprecations
HTTP 0.6
Nullables

4 changes: 2 additions & 2 deletions src/GitHub.jl
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ module GitHub

using Compat
using Compat.Dates
using Nullables

if VERSION >= v"0.7.0-DEV.2338"
using Base64
Expand All @@ -15,8 +16,7 @@ end

import HTTP,
JSON,
MbedTLS,
HttpCommon # for deprecations
MbedTLS

########
# init #
Expand Down
59 changes: 22 additions & 37 deletions src/activity/events.jl
Original file line number Diff line number Diff line change
Expand Up @@ -35,15 +35,15 @@ end
# Validation Functions #
########################

has_event_header(request::HTTP.Request) = haskey(HTTP.headers(request), "X-Github-Event")
event_header(request::HTTP.Request) = HTTP.headers(request)["X-Github-Event"]
has_event_header(request::HTTP.Request) = HTTP.hasheader(request, "X-Github-Event")
event_header(request::HTTP.Request) = HTTP.header(request, "X-Github-Event")

has_sig_header(request::HTTP.Request) = haskey(HTTP.headers(request), "X-Hub-Signature")
sig_header(request::HTTP.Request) = HTTP.headers(request)["X-Hub-Signature"]
has_sig_header(request::HTTP.Request) = HTTP.hasheader(request, "X-Hub-Signature")
sig_header(request::HTTP.Request) = HTTP.header(request, "X-Hub-Signature")

function has_valid_secret(request::HTTP.Request, secret)
if has_sig_header(request)
secret_sha = "sha1="*bytes2hex(MbedTLS.digest(MbedTLS.MD_SHA1, String(request), secret))
secret_sha = "sha1="*bytes2hex(MbedTLS.digest(MbedTLS.MD_SHA1, HTTP.load(request), secret))
return sig_header(request) == secret_sha
end
return false
Expand All @@ -62,69 +62,54 @@ end
#################

struct EventListener
server::HTTP.Server
handle_request
repos
events
function EventListener(handle; auth::Authorization = AnonymousAuth(),
secret = nothing, events = nothing,
repos = nothing, forwards = nothing)
if !(isa(forwards, Void))
if !(isa(forwards, Nothing))
forwards = map(HTTP.URI, forwards)
end

if !(isa(repos, Void))
if !(isa(repos, Nothing))
repos = map(name, repos)
end

server = HTTP.Server() do request, response
try
handle_event_request(request, handle; auth = auth,
secret = secret, events = events,
repos = repos, forwards = forwards)
catch err
bt = catch_backtrace()
print(STDERR, "SERVER ERROR: ")
Base.showerror(STDERR, err, bt)
return HTTP.Response(500)
end
end
handle_request = request::HTTP.Request ->
handle_event_request(request, handle; auth = auth,
secret = secret, events = events,
repos = repos, forwards = forwards)

return new(server, repos, events)
return new(handle_request, repos, events)
end
end

function handle_event_request(request, handle;
auth::Authorization = AnonymousAuth(),
secret = nothing, events = nothing,
repos = nothing, forwards = nothing)
if !(isa(secret, Void)) && !(has_valid_secret(request, secret))
if !(isa(secret, Nothing)) && !(has_valid_secret(request, secret))
return HTTP.Response(400, "invalid signature")
end

if !(isa(events, Void)) && !(is_valid_event(request, events))
if !(isa(events, Nothing)) && !(is_valid_event(request, events))
return HTTP.Response(204, "event ignored")
end

event = event_from_payload!(event_header(request), JSON.parse(String(request)))
event = event_from_payload!(event_header(request), JSON.parse(HTTP.load(request)))

if !(isa(repos, Void)) && !(from_valid_repo(event, repos))
if !(isa(repos, Nothing)) && !(from_valid_repo(event, repos))
return HTTP.Response(400, "invalid repo")
end

if !(isa(forwards, Void))
if !(isa(forwards, Nothing))
for address in forwards
HTTP.post(address, request)
end
end

retval = handle(event)
if retval isa HttpCommon.Response
Base.depwarn("event handlers should return an `HTTP.Response` instead of an `HttpCommon.Response`,
making a best effort to convert to an `HTTP.Response`", :handle_event_request)
retval = HTTP.Response(; status = retval.status, headers = convert(Dict{String, String}, retval.headers),
body = HTTP.FIFOBuffer(retval.data))
end
return retval
return handle(event)
end

function Base.run(listener, args...; host = nothing, port = nothing, kwargs...)
Expand All @@ -136,9 +121,9 @@ end

function Base.run(listener::EventListener, host::HTTP.IPAddr, port::Int, args...; kwargs...)
println("Listening for GitHub events sent to $port;")
println("Whitelisted events: $(isa(listener.events, Void) ? "All" : listener.events)")
println("Whitelisted repos: $(isa(listener.repos, Void) ? "All" : listener.repos)")
return HTTP.serve(listener.server, host, port, args...; kwargs...)
println("Whitelisted events: $(isa(listener.events, Nothing) ? "All" : listener.events)")
println("Whitelisted repos: $(isa(listener.repos, Nothing) ? "All" : listener.repos)")
HTTP.listen(listener.handle_request, host, port; kwargs...)
end

###################
Expand Down
2 changes: 1 addition & 1 deletion src/apps/installations.jl
Original file line number Diff line number Diff line change
Expand Up @@ -25,5 +25,5 @@ end
headers["Accept"] = "application/vnd.github.machine-man-preview+json"
results, page_data = github_paged_get(api, "/installation/repositories";
headers=headers, options...)
mapreduce(x->map(Repo, JSON.parse(String(x))["repositories"]), vcat, Repo[], results), page_data
mapreduce(x->map(Repo, JSON.parse(HTTP.load(x))["repositories"]), vcat, Repo[], results), page_data
end
2 changes: 1 addition & 1 deletion src/git/blob.jl
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
mutable struct Blob <: GitHubType
content::Nullable{String}
encoding::Nullable{String}
url::Nullable{HttpCommon.URI}
url::Nullable{HTTP.URI}
sha::Nullable{String}
size::Nullable{Int}
end
Expand Down
2 changes: 1 addition & 1 deletion src/git/gitcommit.jl
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
mutable struct GitCommit <: GitHubType
sha::Nullable{String}
url::Nullable{HttpCommon.URI}
url::Nullable{HTTP.URI}
author::Nullable{Dict}
commiter::Nullable{Dict}
message::Nullable{String}
Expand Down
2 changes: 1 addition & 1 deletion src/git/reference.jl
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
mutable struct Reference <: GitHubType
ref::Nullable{String}
url::Nullable{HttpCommon.URI}
url::Nullable{HTTP.URI}
object::Nullable{Dict}
end

Expand Down
2 changes: 1 addition & 1 deletion src/git/tag.jl
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
mutable struct Tag <: GitHubType
tag::Nullable{String}
sha::Nullable{String}
url::Nullable{HttpCommon.URI}
url::Nullable{HTTP.URI}
message::Nullable{String}
tagger::Nullable{Dict}
object::Nullable{Dict}
Expand Down
2 changes: 1 addition & 1 deletion src/git/tree.jl
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
mutable struct Tree <: GitHubType
sha::Nullable{String}
url::Nullable{HttpCommon.URI}
url::Nullable{HTTP.URI}
tree::Nullable{Vector}
truncated::Nullable{Bool}
end
Expand Down
2 changes: 1 addition & 1 deletion src/repositories/contents.jl
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ function permalink(content::Content, commit)
prefix = get(content.typ) == "file" ? "blob" : "tree"
rgx = Regex(string("/", prefix, "/.*?/"))
replacement = string("/", prefix, "/", name(commit), "/")
return HTTP.URI(replace(url, rgx, replacement))
return HTTP.URI(replace(url, rgx => replacement))
end

###########################
Expand Down
2 changes: 1 addition & 1 deletion src/utils/GitHubType.jl
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ name(g::GitHubType) = get(namefield(g))
function extract_nullable(data::Dict, key, ::Type{T}) where {T}
if haskey(data, key)
val = data[key]
if !(isa(val, Void))
if !(isa(val, Nothing))
if T <: Vector
V = eltype(T)
return Nullable{T}(V[prune_github_value(v, V) for v in val])
Expand Down
2 changes: 1 addition & 1 deletion src/utils/auth.jl
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ end
####################

function base64_to_base64url(string)
replace(replace(replace(string, "=", ""), '+', '-'), '/', '_')
replace(replace(replace(string, "=" => ""), '+' => '-'), '/' => '_')
end

function JWTAuth(app_id::Int, key::MbedTLS.PKContext; iat = now(Dates.UTC), exp_mins = 1)
Expand Down
Loading

0 comments on commit 33e3dd4

Please sign in to comment.