guillotine 1.0.1 → 1.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -13,8 +13,8 @@ Gem::Specification.new do |s|
13
13
  ## If your rubyforge_project name is different, then edit it and comment out
14
14
  ## the sub! line in the Rakefile
15
15
  s.name = 'guillotine'
16
- s.version = '1.0.1'
17
- s.date = '2011-09-29'
16
+ s.version = '1.0.2'
17
+ s.date = '2011-10-11'
18
18
  s.rubyforge_project = 'guillotine'
19
19
 
20
20
  ## Make sure your summary is short. The description may be as long
@@ -1,8 +1,9 @@
1
1
  require 'base64'
2
2
  require 'digest/md5'
3
+ require 'addressable/uri'
3
4
 
4
5
  module Guillotine
5
- VERSION = "1.0.1"
6
+ VERSION = "1.0.2"
6
7
 
7
8
  dir = File.expand_path '../guillotine', __FILE__
8
9
  autoload :App, "#{dir}/app"
@@ -42,6 +43,17 @@ module Guillotine
42
43
  def shorten(url)
43
44
  Base64.urlsafe_encode64([Digest::MD5.hexdigest(url).to_i(16)].pack("N")).sub(/==\n?$/, '')
44
45
  end
46
+
47
+ # Parses and sanitizes a URL.
48
+ #
49
+ # url - A String URL.
50
+ #
51
+ # Returns an Addressable::URI.
52
+ def parse_url(url)
53
+ url.gsub! /\s/, ''
54
+ url.downcase!
55
+ Addressable::URI.parse url
56
+ end
45
57
  end
46
58
  end
47
59
  end
@@ -2,6 +2,7 @@ module Guillotine
2
2
  module Adapters
3
3
  # Stores shortened URLs in memory. Totally scales.
4
4
  class MemoryAdapter < Adapter
5
+ attr_reader :hash, :urls
5
6
  def initialize
6
7
  @hash = {}
7
8
  @urls = {}
@@ -1,5 +1,4 @@
1
1
  require 'sinatra/base'
2
- require 'addressable/uri'
3
2
 
4
3
  module Guillotine
5
4
  class App < Sinatra::Base
@@ -8,15 +7,14 @@ module Guillotine
8
7
  get "/:code" do
9
8
  code = params[:code]
10
9
  if url = settings.db.find(code)
11
- redirect url
10
+ redirect settings.db.parse_url(url).to_s
12
11
  else
13
12
  halt 404, "No url found for #{code}"
14
13
  end
15
14
  end
16
15
 
17
16
  post "/" do
18
- url = Addressable::URI.parse params[:url]
19
- code = params[:code]
17
+ url = settings.db.parse_url params[:url].to_s
20
18
 
21
19
  if !(url && url.scheme =~ /^https?$/)
22
20
  halt 422, "Invalid url: #{url}"
@@ -34,7 +32,7 @@ module Guillotine
34
32
  end
35
33
 
36
34
  begin
37
- if code = settings.db.add(url.to_s.strip, code)
35
+ if code = settings.db.add(url.to_s, params[:code])
38
36
  redirect code, 201
39
37
  else
40
38
  halt 422, "Unable to shorten #{url}"
@@ -22,7 +22,7 @@ class AppTest < Guillotine::TestCase
22
22
  url = 'http://github.com'
23
23
  code = ADAPTER.add url
24
24
 
25
- post '/', :url => url
25
+ post '/', :url => url.upcase
26
26
  assert code_url = last_response.headers['Location']
27
27
  assert_equal code, code_url.gsub(/.*\//, '')
28
28
  end
@@ -38,6 +38,15 @@ class AppTest < Guillotine::TestCase
38
38
  assert_equal url, last_response.headers['Location']
39
39
  end
40
40
 
41
+ def test_redirects_to_split_url
42
+ url = "http://abc.com\nhttp//def.com"
43
+ ADAPTER.hash['split'] = url
44
+ ADAPTER.urls[url] = 'split'
45
+
46
+ get '/split'
47
+ assert_equal "http://abc.comhttp//def.com", last_response.headers['location']
48
+ end
49
+
41
50
  def test_clashing_urls_raises_error
42
51
  code = ADAPTER.add 'http://github.com/123'
43
52
  post '/', :url => 'http://github.com/456', :code => code
@@ -54,6 +63,13 @@ class AppTest < Guillotine::TestCase
54
63
  assert_equal 'http://example.org/SWtBvQ', last_response.headers['location']
55
64
  end
56
65
 
66
+ def test_adds_split_url
67
+ post '/', :url => "https://abc.com\nhttp://abc.com"
68
+ assert_equal 'http://example.org/cb5CNA', last_response.headers['location']
69
+
70
+ assert_equal 'https://abc.comhttp//abc.com', ADAPTER.find('cb5CNA')
71
+ end
72
+
57
73
  def test_rejects_non_http_urls
58
74
  post '/', :url => 'ftp://abc.com'
59
75
  assert_equal 422, last_response.status
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: guillotine
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.1
4
+ version: 1.0.2
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,11 +9,11 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2011-09-29 00:00:00.000000000Z
12
+ date: 2011-10-11 00:00:00.000000000Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: sinatra
16
- requirement: &70118940049540 !ruby/object:Gem::Requirement
16
+ requirement: &70100650093440 !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
19
  - - ~>
@@ -21,10 +21,10 @@ dependencies:
21
21
  version: 1.2.6
22
22
  type: :runtime
23
23
  prerelease: false
24
- version_requirements: *70118940049540
24
+ version_requirements: *70100650093440
25
25
  - !ruby/object:Gem::Dependency
26
26
  name: addressable
27
- requirement: &70118940049020 !ruby/object:Gem::Requirement
27
+ requirement: &70100650092860 !ruby/object:Gem::Requirement
28
28
  none: false
29
29
  requirements:
30
30
  - - ~>
@@ -32,10 +32,10 @@ dependencies:
32
32
  version: 2.2.6
33
33
  type: :runtime
34
34
  prerelease: false
35
- version_requirements: *70118940049020
35
+ version_requirements: *70100650092860
36
36
  - !ruby/object:Gem::Dependency
37
37
  name: rack-test
38
- requirement: &70118940048460 !ruby/object:Gem::Requirement
38
+ requirement: &70100650092080 !ruby/object:Gem::Requirement
39
39
  none: false
40
40
  requirements:
41
41
  - - ! '>='
@@ -43,7 +43,7 @@ dependencies:
43
43
  version: '0'
44
44
  type: :development
45
45
  prerelease: false
46
- version_requirements: *70118940048460
46
+ version_requirements: *70100650092080
47
47
  description: Adaptable private URL shortener
48
48
  email: technoweenie@gmail.com
49
49
  executables: []