htty 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (90) hide show
  1. data/MIT-LICENSE.rdoc +9 -0
  2. data/README.rdoc +199 -0
  3. data/VERSION +1 -0
  4. data/app/htty.rb +14 -0
  5. data/app/htty/cli.rb +77 -0
  6. data/app/htty/cli/command.rb +185 -0
  7. data/app/htty/cli/commands.rb +43 -0
  8. data/app/htty/cli/commands/address.rb +84 -0
  9. data/app/htty/cli/commands/body_clear.rb +20 -0
  10. data/app/htty/cli/commands/body_request.rb +51 -0
  11. data/app/htty/cli/commands/body_response.rb +59 -0
  12. data/app/htty/cli/commands/body_set.rb +58 -0
  13. data/app/htty/cli/commands/body_unset.rb +45 -0
  14. data/app/htty/cli/commands/cd.rb +20 -0
  15. data/app/htty/cli/commands/cookie_add.rb +20 -0
  16. data/app/htty/cli/commands/cookie_remove.rb +20 -0
  17. data/app/htty/cli/commands/cookies.rb +68 -0
  18. data/app/htty/cli/commands/cookies_add.rb +62 -0
  19. data/app/htty/cli/commands/cookies_clear.rb +20 -0
  20. data/app/htty/cli/commands/cookies_remove.rb +60 -0
  21. data/app/htty/cli/commands/cookies_remove_all.rb +50 -0
  22. data/app/htty/cli/commands/cookies_use.rb +57 -0
  23. data/app/htty/cli/commands/delete.rb +20 -0
  24. data/app/htty/cli/commands/exit.rb +20 -0
  25. data/app/htty/cli/commands/follow.rb +56 -0
  26. data/app/htty/cli/commands/form.rb +20 -0
  27. data/app/htty/cli/commands/form_add.rb +20 -0
  28. data/app/htty/cli/commands/form_clear.rb +26 -0
  29. data/app/htty/cli/commands/form_remove.rb +20 -0
  30. data/app/htty/cli/commands/form_remove_all.rb +20 -0
  31. data/app/htty/cli/commands/fragment_clear.rb +20 -0
  32. data/app/htty/cli/commands/fragment_set.rb +59 -0
  33. data/app/htty/cli/commands/fragment_unset.rb +48 -0
  34. data/app/htty/cli/commands/get.rb +20 -0
  35. data/app/htty/cli/commands/header_set.rb +20 -0
  36. data/app/htty/cli/commands/header_unset.rb +20 -0
  37. data/app/htty/cli/commands/headers_clear.rb +20 -0
  38. data/app/htty/cli/commands/headers_request.rb +70 -0
  39. data/app/htty/cli/commands/headers_response.rb +65 -0
  40. data/app/htty/cli/commands/headers_set.rb +57 -0
  41. data/app/htty/cli/commands/headers_unset.rb +54 -0
  42. data/app/htty/cli/commands/headers_unset_all.rb +48 -0
  43. data/app/htty/cli/commands/help.rb +100 -0
  44. data/app/htty/cli/commands/history.rb +60 -0
  45. data/app/htty/cli/commands/history_verbose.rb +81 -0
  46. data/app/htty/cli/commands/host_set.rb +59 -0
  47. data/app/htty/cli/commands/http_delete.rb +40 -0
  48. data/app/htty/cli/commands/http_get.rb +42 -0
  49. data/app/htty/cli/commands/http_head.rb +36 -0
  50. data/app/htty/cli/commands/http_options.rb +36 -0
  51. data/app/htty/cli/commands/http_post.rb +34 -0
  52. data/app/htty/cli/commands/http_put.rb +29 -0
  53. data/app/htty/cli/commands/http_trace.rb +36 -0
  54. data/app/htty/cli/commands/path_set.rb +54 -0
  55. data/app/htty/cli/commands/port_set.rb +55 -0
  56. data/app/htty/cli/commands/post.rb +20 -0
  57. data/app/htty/cli/commands/put.rb +20 -0
  58. data/app/htty/cli/commands/query_clear.rb +20 -0
  59. data/app/htty/cli/commands/query_set.rb +59 -0
  60. data/app/htty/cli/commands/query_unset.rb +56 -0
  61. data/app/htty/cli/commands/query_unset_all.rb +50 -0
  62. data/app/htty/cli/commands/quit.rb +24 -0
  63. data/app/htty/cli/commands/reuse.rb +74 -0
  64. data/app/htty/cli/commands/scheme_set.rb +69 -0
  65. data/app/htty/cli/commands/status.rb +52 -0
  66. data/app/htty/cli/commands/undo.rb +13 -0
  67. data/app/htty/cli/commands/userinfo_clear.rb +20 -0
  68. data/app/htty/cli/commands/userinfo_set.rb +56 -0
  69. data/app/htty/cli/commands/userinfo_unset.rb +47 -0
  70. data/app/htty/cli/cookie_clearing_command.rb +26 -0
  71. data/app/htty/cli/display.rb +182 -0
  72. data/app/htty/cli/http_method_command.rb +75 -0
  73. data/app/htty/cli/url_escaping.rb +27 -0
  74. data/app/htty/cookies_util.rb +36 -0
  75. data/app/htty/no_location_header_error.rb +12 -0
  76. data/app/htty/no_response_error.rb +12 -0
  77. data/app/htty/no_set_cookie_header_error.rb +13 -0
  78. data/app/htty/ordered_hash.rb +69 -0
  79. data/app/htty/payload.rb +48 -0
  80. data/app/htty/request.rb +471 -0
  81. data/app/htty/requests_util.rb +92 -0
  82. data/app/htty/response.rb +34 -0
  83. data/app/htty/session.rb +29 -0
  84. data/bin/htty +5 -0
  85. data/spec/unit/htty/cli_spec.rb +27 -0
  86. data/spec/unit/htty/ordered_hash_spec.rb +54 -0
  87. data/spec/unit/htty/request_spec.rb +1236 -0
  88. data/spec/unit/htty/response_spec.rb +0 -0
  89. data/spec/unit/htty/session_spec.rb +13 -0
  90. metadata +158 -0
@@ -0,0 +1,48 @@
1
+ # Defines HTTY::CLI::Commands::HeadersUnsetAll.
2
+
3
+ require File.expand_path("#{File.dirname __FILE__}/../command")
4
+ require File.expand_path("#{File.dirname __FILE__}/headers_request")
5
+ require File.expand_path("#{File.dirname __FILE__}/headers_set")
6
+ require File.expand_path("#{File.dirname __FILE__}/headers_unset")
7
+
8
+ module HTTY; end
9
+
10
+ class HTTY::CLI; end
11
+
12
+ module HTTY::CLI::Commands; end
13
+
14
+ # Encapsulates the _headers-unset-all_ command.
15
+ class HTTY::CLI::Commands::HeadersUnsetAll < HTTY::CLI::Command
16
+
17
+ # Returns the name of a category under which help for the _headers-unset-all_
18
+ # command should appear.
19
+ def self.category
20
+ 'Building Requests'
21
+ end
22
+
23
+ # Returns the help text for the _headers-unset-all_ command.
24
+ def self.help
25
+ 'Removes all headers from the request'
26
+ end
27
+
28
+ # Returns the extended help text for the _headers-unset-all_ command.
29
+ def self.help_extended
30
+ 'Removes all headers used for the request. Does not communicate with the ' +
31
+ 'endpoint.'
32
+ end
33
+
34
+ # Returns related command classes for the _headers-unset-all_ command.
35
+ def self.see_also_commands
36
+ [HTTY::CLI::Commands::HeadersRequest,
37
+ HTTY::CLI::Commands::HeadersUnset,
38
+ HTTY::CLI::Commands::HeadersSet]
39
+ end
40
+
41
+ # Performs the _headers-unset-all_ command.
42
+ def perform
43
+ add_request_if_has_response do |request|
44
+ request.headers_unset_all(*arguments)
45
+ end
46
+ end
47
+
48
+ end
@@ -0,0 +1,100 @@
1
+ # Defines HTTY::CLI::Commands::Help.
2
+
3
+ require File.expand_path("#{File.dirname __FILE__}/../command")
4
+ require File.expand_path("#{File.dirname __FILE__}/../commands")
5
+ require File.expand_path("#{File.dirname __FILE__}/../display")
6
+
7
+ module HTTY; end
8
+
9
+ class HTTY::CLI; end
10
+
11
+ module HTTY::CLI::Commands; end
12
+
13
+ # Encapsulates the _help_ command.
14
+ class HTTY::CLI::Commands::Help < HTTY::CLI::Command
15
+
16
+ include HTTY::CLI::Display
17
+
18
+ # Returns the arguments for the command-line usage of the _help_ command.
19
+ def self.command_line_arguments
20
+ '[command]'
21
+ end
22
+
23
+ # Returns the help text for the _help_ command.
24
+ def self.help
25
+ 'Displays this help table, or help on the specified command'
26
+ end
27
+
28
+ # Performs the _help_ command.
29
+ def perform
30
+ return display_help if arguments.empty?
31
+
32
+ unless arguments.length == 1
33
+ raise ArgumentError,
34
+ "wrong number of arguments (#{arguments.length} for 1)"
35
+ end
36
+
37
+ display_help_for arguments.first
38
+ end
39
+
40
+ private
41
+
42
+ def display_help
43
+ maximum_width = HTTY::CLI::Commands.inject 0 do |max, c|
44
+ width = c.command_line.length + (c.command_line_arguments || '').length
45
+ [max, width].max
46
+ end
47
+ categories_in_order = ['Navigation',
48
+ 'Building Requests',
49
+ 'Issuing Requests',
50
+ 'Inspecting Responses',
51
+ nil]
52
+ HTTY::CLI::Commands.select do |c|
53
+ # Filter out commands not yet implemented.
54
+ c.instance_methods(false).collect(&:to_sym).include?(:perform) ||
55
+ (c.alias_for &&
56
+ c.alias_for.instance_methods(false).collect(&:to_sym).include?(:perform))
57
+ end.group_by(&:category).sort_by do |category, commands|
58
+ # Group commands by category and give the categories a custom order.
59
+ categories_in_order.index category
60
+ end.each do |category, commands|
61
+ category ||= 'Miscellaneous'
62
+ puts
63
+ puts((' ' * ((80 - category.length) / 2)) +
64
+ strong(format(category, :underlined)))
65
+ puts
66
+ commands.each do |c|
67
+ justification = maximum_width - c.command_line.length + 4
68
+ puts indent(strong(c.command_line)) +
69
+ " #{c.command_line_arguments}".ljust(justification) +
70
+ word_wrap_indented(c.help, (2 + maximum_width + 4)..80).lstrip
71
+ end
72
+ end
73
+ puts
74
+ self
75
+ end
76
+
77
+ def display_help_for(argument)
78
+ if (command = HTTY::CLI::Commands.build_for(argument))
79
+ c = command.class
80
+ puts
81
+ puts indent(strong(c.command_line)) + " #{c.command_line_arguments}"
82
+ puts
83
+ puts word_wrap_indented(c.help_extended)
84
+ unless c.see_also_commands.empty?
85
+ puts
86
+ puts indent(strong('See also:'))
87
+ puts
88
+ (c.aliases + c.see_also_commands).each do |see_also_command|
89
+ puts indent("* #{see_also_command.command_line}")
90
+ end
91
+ end
92
+ puts
93
+ return self
94
+ end
95
+ $stderr.puts notice("Can't display help for unrecognized command")
96
+ puts notice("Try typing #{strong self.class.command_line}")
97
+ self
98
+ end
99
+
100
+ end
@@ -0,0 +1,60 @@
1
+ # Defines HTTY::CLI::Commands::History.
2
+
3
+ require File.expand_path("#{File.dirname __FILE__}/../command")
4
+ require File.expand_path("#{File.dirname __FILE__}/../display")
5
+ require File.expand_path("#{File.dirname __FILE__}/history_verbose")
6
+ require File.expand_path("#{File.dirname __FILE__}/reuse")
7
+
8
+ module HTTY; end
9
+
10
+ class HTTY::CLI; end
11
+
12
+ module HTTY::CLI::Commands; end
13
+
14
+ # Encapsulates the _history_ command.
15
+ class HTTY::CLI::Commands::History < HTTY::CLI::Command
16
+
17
+ include HTTY::CLI::Display
18
+
19
+ # Returns the name of a category under which help for the _history_ command
20
+ # should appear.
21
+ def self.category
22
+ 'Navigation'
23
+ end
24
+
25
+ # Returns the help text for the _history_ command.
26
+ def self.help
27
+ 'Displays previous request-response activity in this session'
28
+ end
29
+
30
+ # Returns the extended help text for the _history_ command.
31
+ def self.help_extended
32
+ 'Displays previous request-response activity in this session. Does not ' +
33
+ "communicate with the endpoint.\n" +
34
+ "\n" +
35
+ 'Only a summary of each request-response pair is shown; headers and body ' +
36
+ 'content are omitted.'
37
+ end
38
+
39
+ # Returns related command classes for the _history_ command.
40
+ def self.see_also_commands
41
+ [HTTY::CLI::Commands::HistoryVerbose, HTTY::CLI::Commands::Reuse]
42
+ end
43
+
44
+ # Performs the _history_ command.
45
+ def perform
46
+ requests = session.requests
47
+ number_width = Math.log10(requests.length).to_i + 1
48
+ requests.each_with_index do |request, index|
49
+ next unless request.response
50
+
51
+ number = (index + 1).to_s.rjust(number_width)
52
+ print "#{strong number} "
53
+ show_request request
54
+
55
+ print((' ' * number_width), ' ')
56
+ show_response request.response
57
+ end
58
+ end
59
+
60
+ end
@@ -0,0 +1,81 @@
1
+ # Defines HTTY::CLI::Commands::HistoryVerbose.
2
+
3
+ require File.expand_path("#{File.dirname __FILE__}/../../request")
4
+ require File.expand_path("#{File.dirname __FILE__}/../../response")
5
+ require File.expand_path("#{File.dirname __FILE__}/../command")
6
+ require File.expand_path("#{File.dirname __FILE__}/../display")
7
+ require File.expand_path("#{File.dirname __FILE__}/history")
8
+ require File.expand_path("#{File.dirname __FILE__}/reuse")
9
+
10
+ module HTTY; end
11
+
12
+ class HTTY::CLI; end
13
+
14
+ module HTTY::CLI::Commands; end
15
+
16
+ # Encapsulates the _history-verbose_ command.
17
+ class HTTY::CLI::Commands::HistoryVerbose < HTTY::CLI::Command
18
+
19
+ include HTTY::CLI::Display
20
+
21
+ # Returns the name of a category under which help for the _history-verbose_
22
+ # command should appear.
23
+ def self.category
24
+ 'Navigation'
25
+ end
26
+
27
+ # Returns the help text for the _history_ command.
28
+ def self.help
29
+ 'Displays the details of previous request-response activity in this session'
30
+ end
31
+
32
+ # Returns the extended help text for the _history_ command.
33
+ def self.help_extended
34
+ 'Displays the details of previous request-response activity in this ' +
35
+ "session. Does not communicate with the endpoint.\n" +
36
+ "\n" +
37
+ 'All headers and body content of each request-response pair are shown.'
38
+ end
39
+
40
+ # Returns related command classes for the _history-verbose_ command.
41
+ def self.see_also_commands
42
+ [HTTY::CLI::Commands::History, HTTY::CLI::Commands::Reuse]
43
+ end
44
+
45
+ # Performs the _history-verbose_ command.
46
+ def perform
47
+ requests = session.requests
48
+ number_width = Math.log10(requests.length).to_i + 1
49
+ displayed_one = false
50
+ requests.each_with_index do |request, index|
51
+ next unless request.response
52
+
53
+ puts(strong('-' * 80)) if displayed_one
54
+ displayed_one = true
55
+
56
+ number = (index + 1).to_s.rjust(number_width)
57
+ print "#{strong number} "
58
+ show_request request
59
+
60
+ puts unless request.headers.empty?
61
+ show_headers request.headers, HTTY::Request::COOKIES_HEADER_NAME
62
+
63
+ unless request.body.to_s.empty?
64
+ puts
65
+ puts request.body
66
+ end
67
+
68
+ puts
69
+ show_response request.response
70
+
71
+ puts unless request.response.headers.empty?
72
+ show_headers request.response.headers, HTTY::Response::COOKIES_HEADER_NAME
73
+
74
+ unless request.response.body.to_s.empty?
75
+ puts
76
+ puts request.response.body
77
+ end
78
+ end
79
+ end
80
+
81
+ end
@@ -0,0 +1,59 @@
1
+ # Defines HTTY::CLI::Commands::HostSet.
2
+
3
+ require File.expand_path("#{File.dirname __FILE__}/../command")
4
+ require File.expand_path("#{File.dirname __FILE__}/../cookie_clearing_command")
5
+ require File.expand_path("#{File.dirname __FILE__}/address")
6
+
7
+ module HTTY; end
8
+
9
+ class HTTY::CLI; end
10
+
11
+ module HTTY::CLI::Commands; end
12
+
13
+ # Encapsulates the _host-set_ command.
14
+ class HTTY::CLI::Commands::HostSet < HTTY::CLI::Command
15
+
16
+ include HTTY::CLI::CookieClearingCommand
17
+
18
+ # Returns the name of a category under which help for the _host-set_ command
19
+ # should appear.
20
+ def self.category
21
+ 'Navigation'
22
+ end
23
+
24
+ # Returns the arguments for the command-line usage of the _host-set_ command.
25
+ def self.command_line_arguments
26
+ 'host'
27
+ end
28
+
29
+ # Returns the help text for the _host-set_ command.
30
+ def self.help
31
+ "Changes the host of the request's address"
32
+ end
33
+
34
+ # Returns the extended help text for the _host-set_ command.
35
+ def self.help_extended
36
+ 'Changes the host used for the request. Does not communicate with the ' +
37
+ "endpoint.\n" +
38
+ "\n" +
39
+ "The host you supply can be either a hostname (e.g., 'github.com') or " +
40
+ "an IP address (e.g., '127.0.0.1').\n" +
41
+ "\n" +
42
+ 'The console prompt shows the address for the current request.'
43
+ end
44
+
45
+ # Returns related command classes for the _host-set_ command.
46
+ def self.see_also_commands
47
+ [HTTY::CLI::Commands::Address]
48
+ end
49
+
50
+ # Performs the _host-set_ command.
51
+ def perform
52
+ add_request_if_has_response do |request|
53
+ notify_if_cookies_cleared request do
54
+ request.host_set(*arguments)
55
+ end
56
+ end
57
+ end
58
+
59
+ end
@@ -0,0 +1,40 @@
1
+ # Defines HTTY::CLI::Commands::HttpDelete.
2
+
3
+ require File.expand_path("#{File.dirname __FILE__}/../command")
4
+ require File.expand_path("#{File.dirname __FILE__}/../http_method_command")
5
+ require File.expand_path("#{File.dirname __FILE__}/http_get")
6
+ require File.expand_path("#{File.dirname __FILE__}/http_post")
7
+ require File.expand_path("#{File.dirname __FILE__}/http_put")
8
+
9
+ module HTTY; end
10
+
11
+ class HTTY::CLI; end
12
+
13
+ module HTTY::CLI::Commands; end
14
+
15
+ # Encapsulates the _http-delete_ command.
16
+ class HTTY::CLI::Commands::HttpDelete < HTTY::CLI::Command
17
+
18
+ include HTTY::CLI::HTTPMethodCommand
19
+
20
+ # Returns the help text for the _http-delete_ command.
21
+ def self.help
22
+ 'Issues an HTTP DELETE using the current request'
23
+ end
24
+
25
+ # Returns the extended help text for the _http-delete_ command.
26
+ def self.help_extended
27
+ "Issues an HTTP DELETE using the current request.\n" +
28
+ "\n" +
29
+ 'Any request body you may set is ignored (i.e., it is not sent as part ' +
30
+ 'of the request).'
31
+ end
32
+
33
+ # Returns related command classes for the _http-delete_ command.
34
+ def self.see_also_commands
35
+ [HTTY::CLI::Commands::HttpGet,
36
+ HTTY::CLI::Commands::HttpPost,
37
+ HTTY::CLI::Commands::HttpPut]
38
+ end
39
+
40
+ end
@@ -0,0 +1,42 @@
1
+ # Defines HTTY::CLI::Commands::HttpGet.
2
+
3
+ require File.expand_path("#{File.dirname __FILE__}/../command")
4
+ require File.expand_path("#{File.dirname __FILE__}/../http_method_command")
5
+ require File.expand_path("#{File.dirname __FILE__}/follow")
6
+ require File.expand_path("#{File.dirname __FILE__}/http_delete")
7
+ require File.expand_path("#{File.dirname __FILE__}/http_post")
8
+ require File.expand_path("#{File.dirname __FILE__}/http_put")
9
+
10
+ module HTTY; end
11
+
12
+ class HTTY::CLI; end
13
+
14
+ module HTTY::CLI::Commands; end
15
+
16
+ # Encapsulates the _http-get_ command.
17
+ class HTTY::CLI::Commands::HttpGet < HTTY::CLI::Command
18
+
19
+ include HTTY::CLI::HTTPMethodCommand
20
+
21
+ # Returns the help text for the _http-get_ command.
22
+ def self.help
23
+ 'Issues an HTTP GET using the current request'
24
+ end
25
+
26
+ # Returns the extended help text for the _http-get_ command.
27
+ def self.help_extended
28
+ "Issues an HTTP GET using the current request.\n" +
29
+ "\n" +
30
+ 'Any request body you may set is ignored (i.e., it is not sent as part ' +
31
+ 'of the request).'
32
+ end
33
+
34
+ # Returns related command classes for the _http-get_ command.
35
+ def self.see_also_commands
36
+ [HTTY::CLI::Commands::Follow,
37
+ HTTY::CLI::Commands::HttpPost,
38
+ HTTY::CLI::Commands::HttpPut,
39
+ HTTY::CLI::Commands::HttpDelete]
40
+ end
41
+
42
+ end
@@ -0,0 +1,36 @@
1
+ # Defines HTTY::CLI::Commands::HttpHead.
2
+
3
+ require File.expand_path("#{File.dirname __FILE__}/../command")
4
+ require File.expand_path("#{File.dirname __FILE__}/../http_method_command")
5
+ require File.expand_path("#{File.dirname __FILE__}/http_get")
6
+
7
+ module HTTY; end
8
+
9
+ class HTTY::CLI; end
10
+
11
+ module HTTY::CLI::Commands; end
12
+
13
+ # Encapsulates the _http-head_ command.
14
+ class HTTY::CLI::Commands::HttpHead < HTTY::CLI::Command
15
+
16
+ include HTTY::CLI::HTTPMethodCommand
17
+
18
+ # Returns the help text for the _http-head_ command.
19
+ def self.help
20
+ 'Issues an HTTP HEAD using the current request'
21
+ end
22
+
23
+ # Returns the extended help text for the _http-head_ command.
24
+ def self.help_extended
25
+ "Issues an HTTP HEAD using the current request.\n" +
26
+ "\n" +
27
+ 'Any request body you may set is ignored (i.e., it is not sent as part ' +
28
+ 'of the request).'
29
+ end
30
+
31
+ # Returns related command classes for the _http-head_ command.
32
+ def self.see_also_commands
33
+ [HTTY::CLI::Commands::HttpGet]
34
+ end
35
+
36
+ end