guillotine 1.0.1 → 1.0.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -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: []