net-http 0.3.1 → 0.4.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Gemfile +1 -0
- data/Rakefile +0 -7
- data/doc/net-http/examples.rdoc +2 -1
- data/doc/net-http/included_getters.rdoc +3 -0
- data/lib/net/http/backward.rb +1 -1
- data/lib/net/http/exceptions.rb +1 -1
- data/lib/net/http/generic_request.rb +91 -15
- data/lib/net/http/header.rb +273 -117
- data/lib/net/http/proxy_delta.rb +1 -1
- data/lib/net/http/request.rb +50 -5
- data/lib/net/http/requests.rb +31 -1
- data/lib/net/http/response.rb +42 -22
- data/lib/net/http/responses.rb +931 -69
- data/lib/net/http/status.rb +7 -6
- data/lib/net/http.rb +1162 -445
- data/lib/net/https.rb +1 -1
- data/net-http.gemspec +9 -4
- metadata +4 -6
- data/.github/dependabot.yml +0 -6
- data/.github/workflows/test.yml +0 -22
- data/.gitignore +0 -7
data/lib/net/http/header.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
# frozen_string_literal:
|
1
|
+
# frozen_string_literal: true
|
2
2
|
#
|
3
3
|
# The \HTTPHeader module provides access to \HTTP headers.
|
4
4
|
#
|
@@ -179,6 +179,8 @@
|
|
179
179
|
# - #each_value: Passes each string field value to the block.
|
180
180
|
#
|
181
181
|
module Net::HTTPHeader
|
182
|
+
MAX_KEY_LENGTH = 1024
|
183
|
+
MAX_FIELD_LENGTH = 65536
|
182
184
|
|
183
185
|
def initialize_http_header(initheader) #:nodoc:
|
184
186
|
@header = {}
|
@@ -189,6 +191,12 @@ module Net::HTTPHeader
|
|
189
191
|
warn "net/http: nil HTTP header: #{key}", uplevel: 3 if $VERBOSE
|
190
192
|
else
|
191
193
|
value = value.strip # raise error for invalid byte sequences
|
194
|
+
if key.to_s.bytesize > MAX_KEY_LENGTH
|
195
|
+
raise ArgumentError, "too long (#{key.bytesize} bytes) header: #{key[0, 30].inspect}..."
|
196
|
+
end
|
197
|
+
if value.to_s.bytesize > MAX_FIELD_LENGTH
|
198
|
+
raise ArgumentError, "header #{key} has too long field value: #{value.bytesize}"
|
199
|
+
end
|
192
200
|
if value.count("\r\n") > 0
|
193
201
|
raise ArgumentError, "header #{key} has field value #{value.inspect}, this cannot include CR/LF"
|
194
202
|
end
|
@@ -207,9 +215,7 @@ module Net::HTTPHeader
|
|
207
215
|
# or +nil+ if there is no such key;
|
208
216
|
# see {Fields}[rdoc-ref:Net::HTTPHeader@Fields]:
|
209
217
|
#
|
210
|
-
# res = Net::HTTP.
|
211
|
-
# http.get('/todos/1')
|
212
|
-
# end
|
218
|
+
# res = Net::HTTP.get_response(hostname, '/todos/1')
|
213
219
|
# res['Connection'] # => "keep-alive"
|
214
220
|
# res['Nosuch'] # => nil
|
215
221
|
#
|
@@ -293,9 +299,7 @@ module Net::HTTPHeader
|
|
293
299
|
# or +nil+ if there is no such field;
|
294
300
|
# see {Fields}[rdoc-ref:Net::HTTPHeader@Fields]:
|
295
301
|
#
|
296
|
-
# res = Net::HTTP.
|
297
|
-
# http.get('/todos/1')
|
298
|
-
# end
|
302
|
+
# res = Net::HTTP.get_response(hostname, '/todos/1')
|
299
303
|
# res.get_fields('Connection') # => ["keep-alive"]
|
300
304
|
# res.get_fields('Nosuch') # => nil
|
301
305
|
#
|
@@ -305,7 +309,7 @@ module Net::HTTPHeader
|
|
305
309
|
@header[stringified_downcased_key].dup
|
306
310
|
end
|
307
311
|
|
308
|
-
#
|
312
|
+
# call-seq:
|
309
313
|
# fetch(key, default_val = nil) {|key| ... } -> object
|
310
314
|
# fetch(key, default_val = nil) -> value or default_val
|
311
315
|
#
|
@@ -314,9 +318,7 @@ module Net::HTTPHeader
|
|
314
318
|
# ignores the +default_val+;
|
315
319
|
# see {Fields}[rdoc-ref:Net::HTTPHeader@Fields]:
|
316
320
|
#
|
317
|
-
# res = Net::HTTP.
|
318
|
-
# http.get('/todos/1')
|
319
|
-
# end
|
321
|
+
# res = Net::HTTP.get_response(hostname, '/todos/1')
|
320
322
|
#
|
321
323
|
# # Field exists; block not called.
|
322
324
|
# res.fetch('Connection') do |value|
|
@@ -343,9 +345,7 @@ module Net::HTTPHeader
|
|
343
345
|
|
344
346
|
# Calls the block with each key/value pair:
|
345
347
|
#
|
346
|
-
# res = Net::HTTP.
|
347
|
-
# http.get('/todos/1')
|
348
|
-
# end
|
348
|
+
# res = Net::HTTP.get_response(hostname, '/todos/1')
|
349
349
|
# res.each_header do |key, value|
|
350
350
|
# p [key, value] if key.start_with?('c')
|
351
351
|
# end
|
@@ -372,20 +372,18 @@ module Net::HTTPHeader
|
|
372
372
|
|
373
373
|
# Calls the block with each field key:
|
374
374
|
#
|
375
|
-
# res = Net::HTTP.
|
376
|
-
# http.get('/todos/1')
|
377
|
-
# end
|
375
|
+
# res = Net::HTTP.get_response(hostname, '/todos/1')
|
378
376
|
# res.each_key do |key|
|
379
377
|
# p key if key.start_with?('c')
|
380
378
|
# end
|
381
379
|
#
|
382
380
|
# Output:
|
383
381
|
#
|
384
|
-
#
|
385
|
-
#
|
386
|
-
#
|
387
|
-
#
|
388
|
-
#
|
382
|
+
# "content-type"
|
383
|
+
# "connection"
|
384
|
+
# "cache-control"
|
385
|
+
# "cf-cache-status"
|
386
|
+
# "cf-ray"
|
389
387
|
#
|
390
388
|
# Returns an enumerator if no block is given.
|
391
389
|
#
|
@@ -399,9 +397,7 @@ module Net::HTTPHeader
|
|
399
397
|
|
400
398
|
# Calls the block with each capitalized field name:
|
401
399
|
#
|
402
|
-
# res = Net::HTTP.
|
403
|
-
# http.get('/todos/1')
|
404
|
-
# end
|
400
|
+
# res = Net::HTTP.get_response(hostname, '/todos/1')
|
405
401
|
# res.each_capitalized_name do |key|
|
406
402
|
# p key if key.start_with?('C')
|
407
403
|
# end
|
@@ -427,9 +423,7 @@ module Net::HTTPHeader
|
|
427
423
|
|
428
424
|
# Calls the block with each string field value:
|
429
425
|
#
|
430
|
-
# res = Net::HTTP.
|
431
|
-
# http.get('/todos/1')
|
432
|
-
# end
|
426
|
+
# res = Net::HTTP.get_response(hostname, '/todos/1')
|
433
427
|
# res.each_value do |value|
|
434
428
|
# p value if value.start_with?('c')
|
435
429
|
# end
|
@@ -554,7 +548,7 @@ module Net::HTTPHeader
|
|
554
548
|
result
|
555
549
|
end
|
556
550
|
|
557
|
-
#
|
551
|
+
# call-seq:
|
558
552
|
# set_range(length) -> length
|
559
553
|
# set_range(offset, length) -> range
|
560
554
|
# set_range(begin..length) -> range
|
@@ -610,8 +604,15 @@ module Net::HTTPHeader
|
|
610
604
|
|
611
605
|
alias range= set_range
|
612
606
|
|
613
|
-
# Returns
|
614
|
-
#
|
607
|
+
# Returns the value of field <tt>'Content-Length'</tt> as an integer,
|
608
|
+
# or +nil+ if there is no such field;
|
609
|
+
# see {Content-Length request header}[https://en.wikipedia.org/wiki/List_of_HTTP_header_fields#content-length-request-header]:
|
610
|
+
#
|
611
|
+
# res = Net::HTTP.get_response(hostname, '/nosuch/1')
|
612
|
+
# res.content_length # => 2
|
613
|
+
# res = Net::HTTP.get_response(hostname, '/todos/1')
|
614
|
+
# res.content_length # => nil
|
615
|
+
#
|
615
616
|
def content_length
|
616
617
|
return nil unless key?('Content-Length')
|
617
618
|
len = self['Content-Length'].slice(/\d+/) or
|
@@ -619,6 +620,20 @@ module Net::HTTPHeader
|
|
619
620
|
len.to_i
|
620
621
|
end
|
621
622
|
|
623
|
+
# Sets the value of field <tt>'Content-Length'</tt> to the given numeric;
|
624
|
+
# see {Content-Length response header}[https://en.wikipedia.org/wiki/List_of_HTTP_header_fields#content-length-response-header]:
|
625
|
+
#
|
626
|
+
# _uri = uri.dup
|
627
|
+
# hostname = _uri.hostname # => "jsonplaceholder.typicode.com"
|
628
|
+
# _uri.path = '/posts' # => "/posts"
|
629
|
+
# req = Net::HTTP::Post.new(_uri) # => #<Net::HTTP::Post POST>
|
630
|
+
# req.body = '{"title": "foo","body": "bar","userId": 1}'
|
631
|
+
# req.content_length = req.body.size # => 42
|
632
|
+
# req.content_type = 'application/json'
|
633
|
+
# res = Net::HTTP.start(hostname) do |http|
|
634
|
+
# http.request(req)
|
635
|
+
# end # => #<Net::HTTPCreated 201 Created readbody=true>
|
636
|
+
#
|
622
637
|
def content_length=(len)
|
623
638
|
unless len
|
624
639
|
@header.delete 'content-length'
|
@@ -627,20 +642,31 @@ module Net::HTTPHeader
|
|
627
642
|
@header['content-length'] = [len.to_i.to_s]
|
628
643
|
end
|
629
644
|
|
630
|
-
# Returns
|
631
|
-
#
|
632
|
-
#
|
633
|
-
#
|
645
|
+
# Returns +true+ if field <tt>'Transfer-Encoding'</tt>
|
646
|
+
# exists and has value <tt>'chunked'</tt>,
|
647
|
+
# +false+ otherwise;
|
648
|
+
# see {Transfer-Encoding response header}[https://en.wikipedia.org/wiki/List_of_HTTP_header_fields#transfer-encoding-response-header]:
|
649
|
+
#
|
650
|
+
# res = Net::HTTP.get_response(hostname, '/todos/1')
|
651
|
+
# res['Transfer-Encoding'] # => "chunked"
|
652
|
+
# res.chunked? # => true
|
653
|
+
#
|
634
654
|
def chunked?
|
635
655
|
return false unless @header['transfer-encoding']
|
636
656
|
field = self['Transfer-Encoding']
|
637
657
|
(/(?:\A|[^\-\w])chunked(?![\-\w])/i =~ field) ? true : false
|
638
658
|
end
|
639
659
|
|
640
|
-
# Returns a Range object
|
641
|
-
#
|
642
|
-
#
|
643
|
-
#
|
660
|
+
# Returns a Range object representing the value of field
|
661
|
+
# <tt>'Content-Range'</tt>, or +nil+ if no such field exists;
|
662
|
+
# see {Content-Range response header}[https://en.wikipedia.org/wiki/List_of_HTTP_header_fields#content-range-response-header]:
|
663
|
+
#
|
664
|
+
# res = Net::HTTP.get_response(hostname, '/todos/1')
|
665
|
+
# res['Content-Range'] # => nil
|
666
|
+
# res['Content-Range'] = 'bytes 0-499/1000'
|
667
|
+
# res['Content-Range'] # => "bytes 0-499/1000"
|
668
|
+
# res.content_range # => 0..499
|
669
|
+
#
|
644
670
|
def content_range
|
645
671
|
return nil unless @header['content-range']
|
646
672
|
m = %r<\A\s*(\w+)\s+(\d+)-(\d+)/(\d+|\*)>.match(self['Content-Range']) or
|
@@ -649,32 +675,66 @@ module Net::HTTPHeader
|
|
649
675
|
m[2].to_i .. m[3].to_i
|
650
676
|
end
|
651
677
|
|
652
|
-
#
|
678
|
+
# Returns the integer representing length of the value of field
|
679
|
+
# <tt>'Content-Range'</tt>, or +nil+ if no such field exists;
|
680
|
+
# see {Content-Range response header}[https://en.wikipedia.org/wiki/List_of_HTTP_header_fields#content-range-response-header]:
|
681
|
+
#
|
682
|
+
# res = Net::HTTP.get_response(hostname, '/todos/1')
|
683
|
+
# res['Content-Range'] # => nil
|
684
|
+
# res['Content-Range'] = 'bytes 0-499/1000'
|
685
|
+
# res.range_length # => 500
|
686
|
+
#
|
653
687
|
def range_length
|
654
688
|
r = content_range() or return nil
|
655
689
|
r.end - r.begin + 1
|
656
690
|
end
|
657
691
|
|
658
|
-
# Returns
|
659
|
-
#
|
692
|
+
# Returns the {media type}[https://en.wikipedia.org/wiki/Media_type]
|
693
|
+
# from the value of field <tt>'Content-Type'</tt>,
|
694
|
+
# or +nil+ if no such field exists;
|
695
|
+
# see {Content-Type response header}[https://en.wikipedia.org/wiki/List_of_HTTP_header_fields#content-type-response-header]:
|
696
|
+
#
|
697
|
+
# res = Net::HTTP.get_response(hostname, '/todos/1')
|
698
|
+
# res['content-type'] # => "application/json; charset=utf-8"
|
699
|
+
# res.content_type # => "application/json"
|
700
|
+
#
|
660
701
|
def content_type
|
661
|
-
|
662
|
-
|
663
|
-
|
664
|
-
|
702
|
+
main = main_type()
|
703
|
+
return nil unless main
|
704
|
+
|
705
|
+
sub = sub_type()
|
706
|
+
if sub
|
707
|
+
"#{main}/#{sub}"
|
708
|
+
else
|
709
|
+
main
|
665
710
|
end
|
666
711
|
end
|
667
712
|
|
668
|
-
# Returns
|
669
|
-
#
|
713
|
+
# Returns the leading ('type') part of the
|
714
|
+
# {media type}[https://en.wikipedia.org/wiki/Media_type]
|
715
|
+
# from the value of field <tt>'Content-Type'</tt>,
|
716
|
+
# or +nil+ if no such field exists;
|
717
|
+
# see {Content-Type response header}[https://en.wikipedia.org/wiki/List_of_HTTP_header_fields#content-type-response-header]:
|
718
|
+
#
|
719
|
+
# res = Net::HTTP.get_response(hostname, '/todos/1')
|
720
|
+
# res['content-type'] # => "application/json; charset=utf-8"
|
721
|
+
# res.main_type # => "application"
|
722
|
+
#
|
670
723
|
def main_type
|
671
724
|
return nil unless @header['content-type']
|
672
725
|
self['Content-Type'].split(';').first.to_s.split('/')[0].to_s.strip
|
673
726
|
end
|
674
727
|
|
675
|
-
# Returns
|
676
|
-
#
|
677
|
-
#
|
728
|
+
# Returns the trailing ('subtype') part of the
|
729
|
+
# {media type}[https://en.wikipedia.org/wiki/Media_type]
|
730
|
+
# from the value of field <tt>'Content-Type'</tt>,
|
731
|
+
# or +nil+ if no such field exists;
|
732
|
+
# see {Content-Type response header}[https://en.wikipedia.org/wiki/List_of_HTTP_header_fields#content-type-response-header]:
|
733
|
+
#
|
734
|
+
# res = Net::HTTP.get_response(hostname, '/todos/1')
|
735
|
+
# res['content-type'] # => "application/json; charset=utf-8"
|
736
|
+
# res.sub_type # => "json"
|
737
|
+
#
|
678
738
|
def sub_type
|
679
739
|
return nil unless @header['content-type']
|
680
740
|
_, sub = *self['Content-Type'].split(';').first.to_s.split('/')
|
@@ -682,9 +742,14 @@ module Net::HTTPHeader
|
|
682
742
|
sub.strip
|
683
743
|
end
|
684
744
|
|
685
|
-
#
|
686
|
-
#
|
687
|
-
#
|
745
|
+
# Returns the trailing ('parameters') part of the value of field <tt>'Content-Type'</tt>,
|
746
|
+
# or +nil+ if no such field exists;
|
747
|
+
# see {Content-Type response header}[https://en.wikipedia.org/wiki/List_of_HTTP_header_fields#content-type-response-header]:
|
748
|
+
#
|
749
|
+
# res = Net::HTTP.get_response(hostname, '/todos/1')
|
750
|
+
# res['content-type'] # => "application/json; charset=utf-8"
|
751
|
+
# res.type_params # => {"charset"=>"utf-8"}
|
752
|
+
#
|
688
753
|
def type_params
|
689
754
|
result = {}
|
690
755
|
list = self['Content-Type'].to_s.split(';')
|
@@ -696,10 +761,12 @@ module Net::HTTPHeader
|
|
696
761
|
result
|
697
762
|
end
|
698
763
|
|
699
|
-
# Sets the
|
700
|
-
#
|
701
|
-
#
|
702
|
-
#
|
764
|
+
# Sets the value of field <tt>'Content-Type'</tt>;
|
765
|
+
# returns the new value;
|
766
|
+
# see {Content-Type request header}[https://en.wikipedia.org/wiki/List_of_HTTP_header_fields#content-type-request-header]:
|
767
|
+
#
|
768
|
+
# req = Net::HTTP::Get.new(uri)
|
769
|
+
# req.set_content_type('application/json') # => ["application/json"]
|
703
770
|
#
|
704
771
|
# Net::HTTPHeader#content_type= is an alias for Net::HTTPHeader#set_content_type.
|
705
772
|
def set_content_type(type, params = {})
|
@@ -708,18 +775,38 @@ module Net::HTTPHeader
|
|
708
775
|
|
709
776
|
alias content_type= set_content_type
|
710
777
|
|
711
|
-
#
|
712
|
-
#
|
713
|
-
#
|
714
|
-
#
|
778
|
+
# Sets the request body to a URL-encoded string derived from argument +params+,
|
779
|
+
# and sets request header field <tt>'Content-Type'</tt>
|
780
|
+
# to <tt>'application/x-www-form-urlencoded'</tt>.
|
781
|
+
#
|
782
|
+
# The resulting request is suitable for HTTP request +POST+ or +PUT+.
|
783
|
+
#
|
784
|
+
# Argument +params+ must be suitable for use as argument +enum+ to
|
785
|
+
# {URI.encode_www_form}[https://docs.ruby-lang.org/en/master/URI.html#method-c-encode_www_form].
|
786
|
+
#
|
787
|
+
# With only argument +params+ given,
|
788
|
+
# sets the body to a URL-encoded string with the default separator <tt>'&'</tt>:
|
715
789
|
#
|
716
|
-
#
|
717
|
-
# application/x-www-form-urlencoded
|
790
|
+
# req = Net::HTTP::Post.new('example.com')
|
718
791
|
#
|
719
|
-
#
|
720
|
-
#
|
721
|
-
#
|
722
|
-
#
|
792
|
+
# req.set_form_data(q: 'ruby', lang: 'en')
|
793
|
+
# req.body # => "q=ruby&lang=en"
|
794
|
+
# req['Content-Type'] # => "application/x-www-form-urlencoded"
|
795
|
+
#
|
796
|
+
# req.set_form_data([['q', 'ruby'], ['lang', 'en']])
|
797
|
+
# req.body # => "q=ruby&lang=en"
|
798
|
+
#
|
799
|
+
# req.set_form_data(q: ['ruby', 'perl'], lang: 'en')
|
800
|
+
# req.body # => "q=ruby&q=perl&lang=en"
|
801
|
+
#
|
802
|
+
# req.set_form_data([['q', 'ruby'], ['q', 'perl'], ['lang', 'en']])
|
803
|
+
# req.body # => "q=ruby&q=perl&lang=en"
|
804
|
+
#
|
805
|
+
# With string argument +sep+ also given,
|
806
|
+
# uses that string as the separator:
|
807
|
+
#
|
808
|
+
# req.set_form_data({q: 'ruby', lang: 'en'}, '|')
|
809
|
+
# req.body # => "q=ruby|lang=en"
|
723
810
|
#
|
724
811
|
# Net::HTTPHeader#form_data= is an alias for Net::HTTPHeader#set_form_data.
|
725
812
|
def set_form_data(params, sep = '&')
|
@@ -731,53 +818,108 @@ module Net::HTTPHeader
|
|
731
818
|
|
732
819
|
alias form_data= set_form_data
|
733
820
|
|
734
|
-
#
|
735
|
-
#
|
736
|
-
#
|
737
|
-
#
|
738
|
-
#
|
739
|
-
#
|
740
|
-
#
|
741
|
-
#
|
742
|
-
#
|
743
|
-
#
|
744
|
-
#
|
745
|
-
#
|
746
|
-
#
|
747
|
-
#
|
748
|
-
#
|
749
|
-
#
|
750
|
-
#
|
751
|
-
#
|
752
|
-
#
|
753
|
-
#
|
754
|
-
#
|
755
|
-
#
|
756
|
-
#
|
757
|
-
#
|
758
|
-
# the
|
759
|
-
#
|
760
|
-
#
|
761
|
-
#
|
762
|
-
#
|
763
|
-
#
|
764
|
-
#
|
765
|
-
#
|
766
|
-
#
|
767
|
-
#
|
768
|
-
#
|
769
|
-
#
|
770
|
-
#
|
771
|
-
#
|
772
|
-
#
|
773
|
-
#
|
774
|
-
#
|
775
|
-
#
|
776
|
-
#
|
777
|
-
#
|
778
|
-
#
|
779
|
-
#
|
780
|
-
#
|
821
|
+
# Stores form data to be used in a +POST+ or +PUT+ request.
|
822
|
+
#
|
823
|
+
# The form data given in +params+ consists of zero or more fields;
|
824
|
+
# each field is:
|
825
|
+
#
|
826
|
+
# - A scalar value.
|
827
|
+
# - A name/value pair.
|
828
|
+
# - An IO stream opened for reading.
|
829
|
+
#
|
830
|
+
# Argument +params+ should be an
|
831
|
+
# {Enumerable}[https://docs.ruby-lang.org/en/master/Enumerable.html#module-Enumerable-label-Enumerable+in+Ruby+Classes]
|
832
|
+
# (method <tt>params.map</tt> will be called),
|
833
|
+
# and is often an array or hash.
|
834
|
+
#
|
835
|
+
# First, we set up a request:
|
836
|
+
#
|
837
|
+
# _uri = uri.dup
|
838
|
+
# _uri.path ='/posts'
|
839
|
+
# req = Net::HTTP::Post.new(_uri)
|
840
|
+
#
|
841
|
+
# <b>Argument +params+ As an Array</b>
|
842
|
+
#
|
843
|
+
# When +params+ is an array,
|
844
|
+
# each of its elements is a subarray that defines a field;
|
845
|
+
# the subarray may contain:
|
846
|
+
#
|
847
|
+
# - One string:
|
848
|
+
#
|
849
|
+
# req.set_form([['foo'], ['bar'], ['baz']])
|
850
|
+
#
|
851
|
+
# - Two strings:
|
852
|
+
#
|
853
|
+
# req.set_form([%w[foo 0], %w[bar 1], %w[baz 2]])
|
854
|
+
#
|
855
|
+
# - When argument +enctype+ (see below) is given as
|
856
|
+
# <tt>'multipart/form-data'</tt>:
|
857
|
+
#
|
858
|
+
# - A string name and an IO stream opened for reading:
|
859
|
+
#
|
860
|
+
# require 'stringio'
|
861
|
+
# req.set_form([['file', StringIO.new('Ruby is cool.')]])
|
862
|
+
#
|
863
|
+
# - A string name, an IO stream opened for reading,
|
864
|
+
# and an options hash, which may contain these entries:
|
865
|
+
#
|
866
|
+
# - +:filename+: The name of the file to use.
|
867
|
+
# - +:content_type+: The content type of the uploaded file.
|
868
|
+
#
|
869
|
+
# Example:
|
870
|
+
#
|
871
|
+
# req.set_form([['file', file, {filename: "other-filename.foo"}]]
|
872
|
+
#
|
873
|
+
# The various forms may be mixed:
|
874
|
+
#
|
875
|
+
# req.set_form(['foo', %w[bar 1], ['file', file]])
|
876
|
+
#
|
877
|
+
# <b>Argument +params+ As a Hash</b>
|
878
|
+
#
|
879
|
+
# When +params+ is a hash,
|
880
|
+
# each of its entries is a name/value pair that defines a field:
|
881
|
+
#
|
882
|
+
# - The name is a string.
|
883
|
+
# - The value may be:
|
884
|
+
#
|
885
|
+
# - +nil+.
|
886
|
+
# - Another string.
|
887
|
+
# - An IO stream opened for reading
|
888
|
+
# (only when argument +enctype+ -- see below -- is given as
|
889
|
+
# <tt>'multipart/form-data'</tt>).
|
890
|
+
#
|
891
|
+
# Examples:
|
892
|
+
#
|
893
|
+
# # Nil-valued fields.
|
894
|
+
# req.set_form({'foo' => nil, 'bar' => nil, 'baz' => nil})
|
895
|
+
#
|
896
|
+
# # String-valued fields.
|
897
|
+
# req.set_form({'foo' => 0, 'bar' => 1, 'baz' => 2})
|
898
|
+
#
|
899
|
+
# # IO-valued field.
|
900
|
+
# require 'stringio'
|
901
|
+
# req.set_form({'file' => StringIO.new('Ruby is cool.')})
|
902
|
+
#
|
903
|
+
# # Mixture of fields.
|
904
|
+
# req.set_form({'foo' => nil, 'bar' => 1, 'file' => file})
|
905
|
+
#
|
906
|
+
# Optional argument +enctype+ specifies the value to be given
|
907
|
+
# to field <tt>'Content-Type'</tt>, and must be one of:
|
908
|
+
#
|
909
|
+
# - <tt>'application/x-www-form-urlencoded'</tt> (the default).
|
910
|
+
# - <tt>'multipart/form-data'</tt>;
|
911
|
+
# see {RFC 7578}[https://www.rfc-editor.org/rfc/rfc7578].
|
912
|
+
#
|
913
|
+
# Optional argument +formopt+ is a hash of options
|
914
|
+
# (applicable only when argument +enctype+
|
915
|
+
# is <tt>'multipart/form-data'</tt>)
|
916
|
+
# that may include the following entries:
|
917
|
+
#
|
918
|
+
# - +:boundary+: The value is the boundary string for the multipart message.
|
919
|
+
# If not given, the boundary is a random string.
|
920
|
+
# See {Boundary}[https://www.rfc-editor.org/rfc/rfc7578#section-4.1].
|
921
|
+
# - +:charset+: Value is the character set for the form submission.
|
922
|
+
# Field names and values of non-file fields should be encoded with this charset.
|
781
923
|
#
|
782
924
|
def set_form(params, enctype='application/x-www-form-urlencoded', formopt={})
|
783
925
|
@body_data = params
|
@@ -793,12 +935,24 @@ module Net::HTTPHeader
|
|
793
935
|
end
|
794
936
|
end
|
795
937
|
|
796
|
-
#
|
938
|
+
# Sets header <tt>'Authorization'</tt> using the given
|
939
|
+
# +account+ and +password+ strings:
|
940
|
+
#
|
941
|
+
# req.basic_auth('my_account', 'my_password')
|
942
|
+
# req['Authorization']
|
943
|
+
# # => "Basic bXlfYWNjb3VudDpteV9wYXNzd29yZA=="
|
944
|
+
#
|
797
945
|
def basic_auth(account, password)
|
798
946
|
@header['authorization'] = [basic_encode(account, password)]
|
799
947
|
end
|
800
948
|
|
801
|
-
#
|
949
|
+
# Sets header <tt>'Proxy-Authorization'</tt> using the given
|
950
|
+
# +account+ and +password+ strings:
|
951
|
+
#
|
952
|
+
# req.proxy_basic_auth('my_account', 'my_password')
|
953
|
+
# req['Proxy-Authorization']
|
954
|
+
# # => "Basic bXlfYWNjb3VudDpteV9wYXNzd29yZA=="
|
955
|
+
#
|
802
956
|
def proxy_basic_auth(account, password)
|
803
957
|
@header['proxy-authorization'] = [basic_encode(account, password)]
|
804
958
|
end
|
@@ -808,6 +962,7 @@ module Net::HTTPHeader
|
|
808
962
|
end
|
809
963
|
private :basic_encode
|
810
964
|
|
965
|
+
# Returns whether the HTTP session is to be closed.
|
811
966
|
def connection_close?
|
812
967
|
token = /(?:\A|,)\s*close\s*(?:\z|,)/i
|
813
968
|
@header['connection']&.grep(token) {return true}
|
@@ -815,6 +970,7 @@ module Net::HTTPHeader
|
|
815
970
|
false
|
816
971
|
end
|
817
972
|
|
973
|
+
# Returns whether the HTTP session is to be kept alive.
|
818
974
|
def connection_keep_alive?
|
819
975
|
token = /(?:\A|,)\s*keep-alive\s*(?:\z|,)/i
|
820
976
|
@header['connection']&.grep(token) {return true}
|
data/lib/net/http/proxy_delta.rb
CHANGED
data/lib/net/http/request.rb
CHANGED
@@ -1,10 +1,55 @@
|
|
1
|
-
# frozen_string_literal:
|
1
|
+
# frozen_string_literal: true
|
2
2
|
|
3
|
-
# This class is the base class for \Net::HTTP request classes
|
4
|
-
# it wraps together the request path and the request headers.
|
5
|
-
#
|
3
|
+
# This class is the base class for \Net::HTTP request classes.
|
6
4
|
# The class should not be used directly;
|
7
|
-
# instead you should use its subclasses.
|
5
|
+
# instead you should use its subclasses, listed below.
|
6
|
+
#
|
7
|
+
# == Creating a Request
|
8
|
+
#
|
9
|
+
# An request object may be created with either a URI or a string hostname:
|
10
|
+
#
|
11
|
+
# require 'net/http'
|
12
|
+
# uri = URI('https://jsonplaceholder.typicode.com/')
|
13
|
+
# req = Net::HTTP::Get.new(uri) # => #<Net::HTTP::Get GET>
|
14
|
+
# req = Net::HTTP::Get.new(uri.hostname) # => #<Net::HTTP::Get GET>
|
15
|
+
#
|
16
|
+
# And with any of the subclasses:
|
17
|
+
#
|
18
|
+
# req = Net::HTTP::Head.new(uri) # => #<Net::HTTP::Head HEAD>
|
19
|
+
# req = Net::HTTP::Post.new(uri) # => #<Net::HTTP::Post POST>
|
20
|
+
# req = Net::HTTP::Put.new(uri) # => #<Net::HTTP::Put PUT>
|
21
|
+
# # ...
|
22
|
+
#
|
23
|
+
# The new instance is suitable for use as the argument to Net::HTTP#request.
|
24
|
+
#
|
25
|
+
# == Request Headers
|
26
|
+
#
|
27
|
+
# A new request object has these header fields by default:
|
28
|
+
#
|
29
|
+
# req.to_hash
|
30
|
+
# # =>
|
31
|
+
# {"accept-encoding"=>["gzip;q=1.0,deflate;q=0.6,identity;q=0.3"],
|
32
|
+
# "accept"=>["*/*"],
|
33
|
+
# "user-agent"=>["Ruby"],
|
34
|
+
# "host"=>["jsonplaceholder.typicode.com"]}
|
35
|
+
#
|
36
|
+
# See:
|
37
|
+
#
|
38
|
+
# - {Request header Accept-Encoding}[https://en.wikipedia.org/wiki/List_of_HTTP_header_fields#Accept-Encoding]
|
39
|
+
# and {Compression and Decompression}[rdoc-ref:Net::HTTP@Compression+and+Decompression].
|
40
|
+
# - {Request header Accept}[https://en.wikipedia.org/wiki/List_of_HTTP_header_fields#accept-request-header].
|
41
|
+
# - {Request header User-Agent}[https://en.wikipedia.org/wiki/List_of_HTTP_header_fields#user-agent-request-header].
|
42
|
+
# - {Request header Host}[https://en.wikipedia.org/wiki/List_of_HTTP_header_fields#host-request-header].
|
43
|
+
#
|
44
|
+
# You can add headers or override default headers:
|
45
|
+
#
|
46
|
+
# # res = Net::HTTP::Get.new(uri, {'foo' => '0', 'bar' => '1'})
|
47
|
+
#
|
48
|
+
# This class (and therefore its subclasses) also includes (indirectly)
|
49
|
+
# module Net::HTTPHeader, which gives access to its
|
50
|
+
# {methods for setting headers}[rdoc-ref:Net::HTTPHeader@Setters].
|
51
|
+
#
|
52
|
+
# == Request Subclasses
|
8
53
|
#
|
9
54
|
# Subclasses for HTTP requests:
|
10
55
|
#
|