net-http 0.3.1 → 0.4.0
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.
- 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
|
#
|