better_rest 0.2.1 → 0.2.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +2 -1
- data/README.md +9 -2
- data/better_rest.gemspec +1 -1
- data/lib/better_rest.rb +72 -13
- data/public/main.css +9 -3
- data/views/index.erb +11 -1
- metadata +1 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e990eb58751881bf19708d2bb4a521c954a07850
|
4
|
+
data.tar.gz: baee501acb9b69804a6b903601e1dc1d96c6e24e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 6840e1c632dd3d70ee43979c40bffdf63585787a016b0fdba43a5d555433e16f0a261df189226d01632bb7e577068823e22e8ecbdcf3adb3ea61340bbdbdf822
|
7
|
+
data.tar.gz: 361612d6422112d2fd219ec56397f859fc1a35e37f3d161b5917ee2ee7ed1112d8b116a523abed26ae86e0be97f2fbcf2ef967364ed85349ea0106c0f0334565
|
data/.gitignore
CHANGED
data/README.md
CHANGED
@@ -8,9 +8,16 @@ BetteR emphasises both a clean and easy to use interface, as well as allowing us
|
|
8
8
|
|
9
9
|
![Screenshot](http://at1as.github.io/github_repo_assets/better-rest-client.jpg)
|
10
10
|
|
11
|
+
### Features
|
12
|
+
|
13
|
+
* Import collections from POSTMAN
|
14
|
+
* Save and load Requests
|
15
|
+
* Attach files to requests
|
16
|
+
* Send parallel requests
|
17
|
+
|
11
18
|
### Usage
|
12
19
|
|
13
|
-
The easiest way to use BetteR is to install it using the [Ruby Gem](http://rubygems.org/gems/better_rest) (note that
|
20
|
+
The easiest way to use BetteR is to install it using the [Ruby Gem](http://rubygems.org/gems/better_rest) (note that I usually keep the gem several commits behind the github repo):
|
14
21
|
```bash
|
15
22
|
$ gem install better_rest
|
16
23
|
```
|
@@ -18,7 +25,7 @@ Or download the repository here for the latest version and launch via:
|
|
18
25
|
```bash
|
19
26
|
$ ./bin/better_rest
|
20
27
|
```
|
21
|
-
To try BetteR, without installing the Gem, it's also hosted on [Heroku](http://better-rest.herokuapp.com/). Note that when run on Heroku,
|
28
|
+
To try BetteR, without installing the Gem, it's also hosted on [Heroku](http://better-rest.herokuapp.com/). Note that when run on Heroku, the build is likely to be from a much older commit.
|
22
29
|
|
23
30
|
### Dependencies
|
24
31
|
|
data/better_rest.gemspec
CHANGED
data/lib/better_rest.rb
CHANGED
@@ -14,6 +14,32 @@ set :views, File.expand_path('../../views', __FILE__)
|
|
14
14
|
helpers do
|
15
15
|
include Rack::Utils
|
16
16
|
alias_method :h, :escape_html
|
17
|
+
|
18
|
+
def parse_cookies(cookies)
|
19
|
+
cookie_hash = {}
|
20
|
+
cookies.each do |c|
|
21
|
+
key, value = c.split('; ').first.split('=', 2)
|
22
|
+
cookie_hash[key] = value
|
23
|
+
end
|
24
|
+
cookie_hash.to_json
|
25
|
+
end
|
26
|
+
|
27
|
+
def stringify_cookies(cookies)
|
28
|
+
JSON.parse(cookies).map { |key, value| "#{key}=#{value}" }.join('; ')
|
29
|
+
end
|
30
|
+
|
31
|
+
def parse_postman_headers(headers)
|
32
|
+
header_hash = {}
|
33
|
+
header_list = headers.strip.split(': ')
|
34
|
+
keys = header_list.select.each_with_index { |str, i| i.even? }
|
35
|
+
values = header_list.select.each_with_index { |str, i| i.odd? }
|
36
|
+
|
37
|
+
keys.each_with_index do |key, index|
|
38
|
+
header_hash[key] = values[index]
|
39
|
+
end
|
40
|
+
header_hash
|
41
|
+
end
|
42
|
+
|
17
43
|
end
|
18
44
|
|
19
45
|
configure do
|
@@ -32,7 +58,8 @@ get '/?' do
|
|
32
58
|
@requests = ["GET","POST","PUT","DELETE","HEAD","OPTIONS","PATCH"]
|
33
59
|
@times = ["1", "2", "5", "10"]
|
34
60
|
@header_hash = {"" => ""}
|
35
|
-
@follow, @
|
61
|
+
@follow, @cookies, @verbose = [true] * 3
|
62
|
+
@ssl, @log_requests = [false] * 2
|
36
63
|
@timeout_interval = 2
|
37
64
|
|
38
65
|
erb :index
|
@@ -53,6 +80,7 @@ post '/request' do
|
|
53
80
|
@verbose = @request_body['verbose'] rescue false
|
54
81
|
@ssl = @request_body['ssl_ver'] rescue false
|
55
82
|
@log_requests = @request_body['logging'] rescue false
|
83
|
+
@cookies = @request_body['cookies'] rescue true
|
56
84
|
@timeout_interval = Integer(@request_body['timeout']) rescue 1
|
57
85
|
@request_body['headers']['User-Agent'] = BETTER_SIGNATURE unless @request_body['headers']['User-Agent']
|
58
86
|
|
@@ -77,6 +105,15 @@ post '/request' do
|
|
77
105
|
request.options[:body] = { file: File.open('tmp/' + @request_body['file'], 'r') }
|
78
106
|
end
|
79
107
|
|
108
|
+
# Attach cookie to header
|
109
|
+
if @cookies && @request_body['headers']['Cookie'].nil?
|
110
|
+
if File.exists? "cookiejar"
|
111
|
+
cookie = File.read("cookiejar")
|
112
|
+
end
|
113
|
+
request.options[:headers]['Cookie'] = stringify_cookies(cookie) unless cookie.empty?
|
114
|
+
end
|
115
|
+
|
116
|
+
|
80
117
|
# Remove unused fields from request
|
81
118
|
request.options.delete(:body) if request.options[:body].empty?
|
82
119
|
if @request_body['user'].empty? || @request_body['password'].empty?
|
@@ -97,6 +134,12 @@ post '/request' do
|
|
97
134
|
end
|
98
135
|
end
|
99
136
|
|
137
|
+
# Write cookie to file
|
138
|
+
if response.headers_hash['set-cookie']
|
139
|
+
cookies = parse_cookies(response.headers_hash['set-cookie'])
|
140
|
+
File.open('cookiejar', 'w') { |file| file.write(cookies) }
|
141
|
+
end
|
142
|
+
|
100
143
|
# Response parameters return to View
|
101
144
|
@response_body = {}
|
102
145
|
request.options[:url] = request.url
|
@@ -110,7 +153,14 @@ post '/request' do
|
|
110
153
|
|
111
154
|
@response_body['return_code'] = response.code
|
112
155
|
@response_body['return_time'] = response.time
|
113
|
-
|
156
|
+
|
157
|
+
# Return body with correct encoding
|
158
|
+
if response.headers_hash['Content-Type'] == "application/json"
|
159
|
+
@response_body['return_body'] = JSON.pretty_generate(JSON.parse(response.body)).force_encoding('ISO-8859-1')
|
160
|
+
else
|
161
|
+
@response_body['return_body'] = response.body.force_encoding('ISO-8859-1')
|
162
|
+
end
|
163
|
+
|
114
164
|
@response_body['return_headers'] = response.response_headers
|
115
165
|
|
116
166
|
@response_body.to_json
|
@@ -168,6 +218,7 @@ get '/savedrequests/:collection/:request' do
|
|
168
218
|
if File.exists? "requests/#{params[:collection]}.json"
|
169
219
|
collection = JSON.parse File.read("requests/#{params[:collection]}.json")
|
170
220
|
request = collection[params[:request]]
|
221
|
+
|
171
222
|
return request.to_json
|
172
223
|
else
|
173
224
|
return 404
|
@@ -178,8 +229,10 @@ end
|
|
178
229
|
|
179
230
|
# Delete Request Collection
|
180
231
|
delete '/collections/:collection' do
|
181
|
-
|
182
|
-
|
232
|
+
collection = "requests/#{params[:collection]}.json"
|
233
|
+
|
234
|
+
if File.exists? collection
|
235
|
+
File.delete(collection)
|
183
236
|
else
|
184
237
|
return 404
|
185
238
|
end
|
@@ -189,11 +242,13 @@ end
|
|
189
242
|
|
190
243
|
# Delete Request from Collection
|
191
244
|
delete '/collections/:collection/:request' do
|
192
|
-
|
193
|
-
|
245
|
+
collection = "requests/#{params[:collection]}.json"
|
246
|
+
|
247
|
+
if File.exists? collection
|
248
|
+
stored_collection = JSON.parse File.read(collection)
|
194
249
|
stored_collection.delete(params[:request])
|
195
250
|
|
196
|
-
File.open(
|
251
|
+
File.open(collection, "w") do |f|
|
197
252
|
f.write(stored_collection.to_json)
|
198
253
|
end
|
199
254
|
else
|
@@ -223,8 +278,10 @@ end
|
|
223
278
|
|
224
279
|
# Delete log
|
225
280
|
delete '/logs/:log' do
|
226
|
-
|
227
|
-
|
281
|
+
log = "logs/#{params[:log]}.log"
|
282
|
+
|
283
|
+
if File.exists? log
|
284
|
+
File.delete(log)
|
228
285
|
else
|
229
286
|
return 404
|
230
287
|
end
|
@@ -250,19 +307,21 @@ end
|
|
250
307
|
# Import from POSTMAN Collection
|
251
308
|
post '/import' do
|
252
309
|
|
310
|
+
file = 'tmp/postman_import.json'
|
311
|
+
|
253
312
|
# Clear tmp directory before writing file
|
254
313
|
FileUtils.rm_rf(Dir.glob('tmp/*'))
|
255
314
|
|
256
315
|
# Save File
|
257
316
|
unless request.body.nil?
|
258
|
-
File.open(
|
317
|
+
File.open(file, 'w') do |f|
|
259
318
|
f.write(params[:file][:tempfile].read)
|
260
319
|
end
|
261
320
|
end
|
262
321
|
|
263
322
|
# Read File
|
264
|
-
if File.exists?
|
265
|
-
stored_collection = JSON.parse File.read(
|
323
|
+
if File.exists? file
|
324
|
+
stored_collection = JSON.parse File.read(file) rescue return 500
|
266
325
|
|
267
326
|
# Data dump of multiple collections
|
268
327
|
if stored_collection['collections']
|
@@ -283,7 +342,7 @@ post '/import' do
|
|
283
342
|
request_details['collection'] = collection['name']
|
284
343
|
request_details['url'] = request['url']
|
285
344
|
request_details['request'] = request['method']
|
286
|
-
request_details['headers'] = request['headers']
|
345
|
+
request_details['headers'] = parse_postman_headers(request['headers'])
|
287
346
|
request_details['payload'] = request['data']
|
288
347
|
request_details['quantity'] = 1
|
289
348
|
|
data/public/main.css
CHANGED
@@ -17,6 +17,9 @@ h2 {
|
|
17
17
|
h2:hover{
|
18
18
|
color:black;
|
19
19
|
}
|
20
|
+
hr{
|
21
|
+
margin-bottom:10px;
|
22
|
+
}
|
20
23
|
input{
|
21
24
|
border-radius: 2px;
|
22
25
|
background-color:#FEFEFE;
|
@@ -239,6 +242,7 @@ ul li:hover ul {
|
|
239
242
|
width: -moz-calc(100% - 40px);
|
240
243
|
width: -webkit-calc(100% - 40px);
|
241
244
|
width: calc(100% - 40px);
|
245
|
+
overflow: hidden;
|
242
246
|
}
|
243
247
|
.rm-collection{
|
244
248
|
line-height:inherit;
|
@@ -311,14 +315,13 @@ ul li:hover ul {
|
|
311
315
|
#auth-span{
|
312
316
|
display:inline-block;
|
313
317
|
white-space:nowrap;
|
314
|
-
margin-top:4px;
|
315
318
|
margin-bottom:4px;
|
316
319
|
margin-left:15px;
|
317
320
|
}
|
318
321
|
#response-status{
|
319
322
|
margin-left:15px;
|
320
323
|
margin-top: 10px;
|
321
|
-
margin-bottom:
|
324
|
+
margin-bottom: 10px;
|
322
325
|
}
|
323
326
|
#response-filters{
|
324
327
|
margin-left:0px;
|
@@ -327,7 +330,7 @@ ul li:hover ul {
|
|
327
330
|
margin-top:4px;
|
328
331
|
}
|
329
332
|
#reqdata{
|
330
|
-
width:
|
333
|
+
width:400px;
|
331
334
|
max-height:300px;
|
332
335
|
overflow:scroll;
|
333
336
|
}
|
@@ -360,6 +363,9 @@ ul li:hover ul {
|
|
360
363
|
overflow:scroll;
|
361
364
|
padding-bottom:15px;
|
362
365
|
}
|
366
|
+
#logs-modal{
|
367
|
+
width:400px;
|
368
|
+
}
|
363
369
|
|
364
370
|
|
365
371
|
/* Tooltips */
|
data/views/index.erb
CHANGED
@@ -194,6 +194,11 @@
|
|
194
194
|
<input type="checkbox" name="followlocation" id="followlocation" class="checkbox" style="float:right"
|
195
195
|
<% if @follow %>checked<% end %>>
|
196
196
|
</div>
|
197
|
+
<div>
|
198
|
+
<label class="form-label conf-label" for="cookies">Send Cookies</label>
|
199
|
+
<input type="checkbox" name="cookies" id="cookies" class="checkbox" style="float:right"
|
200
|
+
<% if @cookies %>checked<% end %>>
|
201
|
+
</div>
|
197
202
|
<div>
|
198
203
|
<label class="form-label conf-label" for="verbose">Verbose Response</label>
|
199
204
|
<input type="checkbox" name="verbose" id="verbose" class="checkbox" style="float:right"
|
@@ -371,6 +376,7 @@
|
|
371
376
|
|
372
377
|
/* SETTINGS */
|
373
378
|
body.redirect = document.getElementById('followlocation').checked;
|
379
|
+
body.cookies = document.getElementById('cookies').checked;
|
374
380
|
body.verbose = document.getElementById('verbose').checked;
|
375
381
|
body.ssl_ver = document.getElementById('ssl_verifypeer').checked;
|
376
382
|
body.logging = document.getElementById('logging').checked;
|
@@ -518,9 +524,10 @@
|
|
518
524
|
client.send();
|
519
525
|
|
520
526
|
if (client.status == 200) {
|
521
|
-
|
527
|
+
modalHideAll();
|
522
528
|
clearFile();
|
523
529
|
populateView(JSON.parse(client.responseText));
|
530
|
+
warn();
|
524
531
|
} else {
|
525
532
|
console.log('Unknown Error: GET ' + url + ' failed');
|
526
533
|
}
|
@@ -565,6 +572,9 @@
|
|
565
572
|
if (fielddata.redirect) {
|
566
573
|
document.getElementById('followlocation').value = fielddata.redirect;
|
567
574
|
}
|
575
|
+
if (fielddata.cookies) {
|
576
|
+
document.getElementById('cookies').value = fielddata.cookies;
|
577
|
+
}
|
568
578
|
if (fielddata.verbose) {
|
569
579
|
document.getElementById('verbose').value = fielddata.verbose;
|
570
580
|
}
|