nice_http 1.4.1 → 1.5.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.
Files changed (3) hide show
  1. checksums.yaml +4 -4
  2. data/lib/nice_http.rb +8 -934
  3. metadata +16 -15
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 92b3f1305bfd51976b8596e6ddd04853221192c098e3a70e967cb204a27588e0
4
- data.tar.gz: '09ee549c83965dab7c7388c66b53ca2896c6e8cc72e0b30ede3a26d93470d9d8'
3
+ metadata.gz: 14ef0915599e45b4cf51c12cd11057661ee6a95167834b832f64364fe84db1d8
4
+ data.tar.gz: a57efa9684af2c57a0156c44f224d9f0d4bbb9a0fcbc35fb38edc41fa0926358
5
5
  SHA512:
6
- metadata.gz: 9dfd50eda432f8b193ed8f3e528913ed54109f9c6f0aff08dcd12bcc96b02fdb490e3f89ed9237c15e8b1a2a788829d479310df28ba80ab5f8cd9a34b0572b47
7
- data.tar.gz: 8045b63b6c1864ce59de6f44279d50358530c2a8fc68a487a19c37793142fffd8e6c0a5330ffe64bbcab8092b2151216db19f2722423033600971f045ef9cfd2
6
+ metadata.gz: 30d1143cd4710c837e37481c8fbbbf385f1e56bfd4804a20bf9665b0349cabe2c4dcdb25e355b107770ad3f95715c56da4c5836c4b1c88b55837fae26bb6a07f
7
+ data.tar.gz: b913a8f5aca115b6370640b27ece8c95099289876490a3d417a656b71b5d16788a9964220efcfb47f7e056ecc3beab0a3a85a2206927bffeae0d705282182d13
@@ -1,6 +1,9 @@
1
1
  require "logger"
2
2
  require "nice_hash"
3
3
  require_relative "nice_http/utils"
4
+ require_relative "nice_http/manage_request"
5
+ require_relative "nice_http/manage_response"
6
+ require_relative "nice_http/http_methods"
4
7
 
5
8
  ######################################################
6
9
  # Attributes you can access using NiceHttp.the_attribute:
@@ -38,6 +41,11 @@ require_relative "nice_http/utils"
38
41
  # @see https://ruby-doc.org/stdlib-2.5.0/libdoc/logger/rdoc/Logger.html
39
42
  ######################################################
40
43
  class NiceHttp
44
+
45
+ include NiceHttpManageRequest
46
+ include NiceHttpManageResponse
47
+ include NiceHttpHttpMethods
48
+
41
49
  Error = Class.new StandardError
42
50
 
43
51
  InfoMissing = Class.new Error do
@@ -290,533 +298,6 @@ class NiceHttp
290
298
  end
291
299
  end
292
300
 
293
- ######################################################
294
- # Get data from path
295
- #
296
- # @param arg [Hash] containing at least key :path
297
- # @param arg [String] the path
298
- #
299
- # @return [Hash] response
300
- # Including at least the symbol keys:
301
- # :data = the response data body.
302
- # :message = plain text response.
303
- # :code = code response (200=ok,500=wrong...).
304
- # All keys in response are lowercase.
305
- # data, message and code can also be accessed as attributes like .message .code .data.
306
- # In case of fatal error returns { fatal_error: "the error description", code: nil, message: nil, data: '' }
307
- #
308
- # @example
309
- # resp = @http.get(Requests::Customer.get_profile)
310
- # assert resp.code == 200
311
- # @example
312
- # resp = @http.get("/customers/1223")
313
- # assert resp.message == "OK"
314
- ######################################################
315
- def get(arg)
316
- begin
317
- path, data, headers_t = manage_request(arg)
318
-
319
- @start_time = Time.now if @start_time.nil?
320
- if @use_mocks and arg.kind_of?(Hash) and arg.keys.include?(:mock_response)
321
- data = ""
322
- if arg[:mock_response].keys.include?(:data)
323
- data = arg[:mock_response][:data]
324
- if data.kind_of?(Hash) #to json
325
- begin
326
- require "json"
327
- data = data.to_json
328
- rescue
329
- @logger.fatal "There was a problem converting to json: #{data}"
330
- end
331
- end
332
- end
333
- @logger.warn "Pay attention!!! This is a mock response:"
334
- @start_time_net = Time.now if @start_time_net.nil?
335
- manage_response(arg[:mock_response], data.to_s)
336
- return @response
337
- end
338
- begin
339
- if path.start_with?("http:") or path.start_with?("https:") #server included on path problably because of a redirection to a different server
340
- require "uri"
341
- uri = URI.parse(path)
342
- ssl = false
343
- ssl = true if path.include?("https:")
344
-
345
- server = "http://"
346
- server = "https://" if path.start_with?("https:")
347
- if uri.port != 443
348
- server += "#{uri.host}:#{uri.port}"
349
- else
350
- server += "#{uri.host}"
351
- end
352
-
353
- http_redir = nil
354
- self.class.connections.each { |conn|
355
- if conn.host == uri.host and conn.port == uri.port
356
- http_redir = conn
357
- break
358
- end
359
- }
360
-
361
- if !http_redir.nil?
362
- path, data, headers_t = manage_request(arg)
363
- http_redir.cookies.merge!(@cookies)
364
- http_redir.headers.merge!(headers_t)
365
- #todo: remove only the server at the begining in case in query is the server it will be replaced when it should not be
366
- resp = http_redir.get(path.gsub(server, ""))
367
- @response = http_redir.response
368
- else
369
- @logger.warn "It seems like the http connection cannot redirect to #{server} because there is no active connection for that server. You need to create previously one."
370
- end
371
- else
372
- @start_time_net = Time.now if @start_time_net.nil?
373
- resp = @http.get(path, headers_t)
374
- data = resp.body
375
- manage_response(resp, data)
376
- end
377
- rescue Exception => stack
378
- @logger.warn stack
379
- @logger.warn "The connection seems to be closed in the host machine. Trying to reconnect"
380
- @http.finish()
381
- @http.start()
382
- @start_time_net = Time.now if @start_time_net.nil?
383
- resp = @http.get(path)
384
- data = resp.body
385
- manage_response(resp, data)
386
- end
387
- if @auto_redirect and @response[:code].to_i >= 300 and @response[:code].to_i < 400 and @response.include?(:location)
388
- if @num_redirects <= 30
389
- @num_redirects += 1
390
- current_server = "http"
391
- current_server += "s" if @ssl == true
392
- current_server += "://#{@host}"
393
- location = @response[:location].gsub(current_server, "")
394
- @logger.info "(#{@num_redirects}) Redirecting NiceHttp to #{location}"
395
- get(location)
396
- else
397
- @logger.fatal "(#{@num_redirects}) Maximum number of redirections for a single request reached. Be sure everything is correct, it seems there is a non ending loop"
398
- @num_redirects = 0
399
- end
400
- else
401
- @num_redirects = 0
402
- end
403
- return @response
404
- rescue Exception => stack
405
- @logger.fatal stack
406
- return {fatal_error: stack.to_s, code: nil, message: nil, data: ""}
407
- end
408
- end
409
-
410
- ######################################################
411
- # Post data to path
412
- # @param arguments [Hash] containing at least keys :data and :path.
413
- # In case :data not supplied and :data_examples array supplied, it will be taken the first example as :data.
414
- # @param arguments [Array<path, data, additional_headers>]
415
- # path (string).
416
- # data (json data for example).
417
- # additional_headers (Hash key=>value).
418
- # @return [Hash] response
419
- # Including at least the symbol keys:
420
- # :data = the response data body.
421
- # :message = plain text response.
422
- # :code = code response (200=ok,500=wrong...).
423
- # All keys in response are lowercase.
424
- # data, message and code can also be accessed as attributes like .message .code .data.
425
- # In case of fatal error returns { fatal_error: "the error description", code: nil, message: nil, data: '' }
426
- # @example
427
- # resp = @http.post(Requests::Customer.update_customer)
428
- # assert resp.code == 201
429
- # @example
430
- # resp = http.post( {
431
- # path: "/api/users",
432
- # data: {name: "morpheus", job: "leader"}
433
- # } )
434
- # pp resp.data.json
435
- ######################################################
436
- def post(*arguments)
437
- begin
438
- path, data, headers_t = manage_request(*arguments)
439
- @start_time = Time.now if @start_time.nil?
440
- if arguments.size > 0 and arguments[0].kind_of?(Hash)
441
- arg = arguments[0]
442
- if @use_mocks and arg.kind_of?(Hash) and arg.keys.include?(:mock_response)
443
- data = ""
444
- if arg[:mock_response].keys.include?(:data)
445
- data = arg[:mock_response][:data]
446
- if data.kind_of?(Hash) #to json
447
- begin
448
- require "json"
449
- data = data.to_json
450
- rescue
451
- @logger.fatal "There was a problem converting to json: #{data}"
452
- end
453
- end
454
- end
455
- @logger.warn "Pay attention!!! This is a mock response:"
456
- @start_time_net = Time.now if @start_time_net.nil?
457
- manage_response(arg[:mock_response], data.to_s)
458
- return @response
459
- end
460
- end
461
-
462
- begin
463
- @start_time_net = Time.now if @start_time_net.nil?
464
- if headers_t["Content-Type"] == "multipart/form-data"
465
- require "net/http/post/multipart"
466
- headers_t.each { |key, value|
467
- arguments[0][:data].add_field(key, value) #add to Headers
468
- }
469
- resp = @http.request(arguments[0][:data])
470
- else
471
- resp = @http.post(path, data, headers_t)
472
- data = resp.body
473
- end
474
- rescue Exception => stack
475
- @logger.warn stack
476
- @logger.warn "The connection seems to be closed in the host machine. Trying to reconnect"
477
- @http.finish()
478
- @http.start()
479
- @start_time_net = Time.now if @start_time_net.nil?
480
- resp, data = @http.post(path, data, headers_t)
481
- end
482
- manage_response(resp, data)
483
- if @auto_redirect and @response[:code].to_i >= 300 and @response[:code].to_i < 400 and @response.include?(:location)
484
- if @num_redirects <= 30
485
- @num_redirects += 1
486
- current_server = "http"
487
- current_server += "s" if @ssl == true
488
- current_server += "://#{@host}"
489
- location = @response[:location].gsub(current_server, "")
490
- @logger.info "(#{@num_redirects}) Redirecting NiceHttp to #{location}"
491
- get(location)
492
- else
493
- @logger.fatal "(#{@num_redirects}) Maximum number of redirections for a single request reached. Be sure everything is correct, it seems there is a non ending loop"
494
- @num_redirects = 0
495
- end
496
- else
497
- @num_redirects = 0
498
- end
499
- return @response
500
- rescue Exception => stack
501
- @logger.fatal stack
502
- return {fatal_error: stack.to_s, code: nil, message: nil, data: ""}
503
- end
504
- end
505
-
506
- ######################################################
507
- # Put data to path
508
- # @param arguments [Hash] containing at least keys :data and :path.
509
- # In case :data not supplied and :data_examples array supplied, it will be taken the first example as :data.
510
- # @param arguments [Array<path, data, additional_headers>]
511
- # path (string).
512
- # data (json data for example).
513
- # additional_headers (Hash key=>value).
514
- # @return [Hash] response
515
- # Including at least the symbol keys:
516
- # :data = the response data body.
517
- # :message = plain text response.
518
- # :code = code response (200=ok,500=wrong...).
519
- # All keys in response are lowercase.
520
- # data, message and code can also be accessed as attributes like .message .code .data.
521
- # In case of fatal error returns { fatal_error: "the error description", code: nil, message: nil, data: '' }
522
- # @example
523
- # resp = @http.put(Requests::Customer.remove_phone)
524
- ######################################################
525
- def put(*arguments)
526
- begin
527
- path, data, headers_t = manage_request(*arguments)
528
- @start_time = Time.now if @start_time.nil?
529
- if arguments.size > 0 and arguments[0].kind_of?(Hash)
530
- arg = arguments[0]
531
- if @use_mocks and arg.kind_of?(Hash) and arg.keys.include?(:mock_response)
532
- data = ""
533
- if arg[:mock_response].keys.include?(:data)
534
- data = arg[:mock_response][:data]
535
- if data.kind_of?(Hash) #to json
536
- begin
537
- require "json"
538
- data = data.to_json
539
- rescue
540
- @logger.fatal "There was a problem converting to json: #{data}"
541
- end
542
- end
543
- end
544
- @logger.warn "Pay attention!!! This is a mock response:"
545
- @start_time_net = Time.now if @start_time_net.nil?
546
- manage_response(arg[:mock_response], data.to_s)
547
- return @response
548
- end
549
- end
550
-
551
- begin
552
- @start_time_net = Time.now if @start_time_net.nil?
553
- resp = @http.send_request("PUT", path, data, headers_t)
554
- data = resp.body
555
- rescue Exception => stack
556
- @logger.warn stack
557
- @logger.warn "The connection seems to be closed in the host machine. Trying to reconnect"
558
- @http.finish()
559
- @http.start()
560
- @start_time_net = Time.now if @start_time_net.nil?
561
- resp, data = @http.send_request("PUT", path, data, headers_t)
562
- end
563
- manage_response(resp, data)
564
-
565
- return @response
566
- rescue Exception => stack
567
- @logger.fatal stack
568
- return {fatal_error: stack.to_s, code: nil, message: nil, data: ""}
569
- end
570
- end
571
-
572
- ######################################################
573
- # Patch data to path
574
- # @param arguments [Hash] containing at least keys :data and :path.
575
- # In case :data not supplied and :data_examples array supplied, it will be taken the first example as :data.
576
- # @param arguments [Array<path, data, additional_headers>]
577
- # path (string).
578
- # data (json data for example).
579
- # additional_headers (Hash key=>value).
580
- # @return [Hash] response
581
- # Including at least the symbol keys:
582
- # :data = the response data body.
583
- # :message = plain text response.
584
- # :code = code response (200=ok,500=wrong...).
585
- # All keys in response are lowercase.
586
- # data, message and code can also be accessed as attributes like .message .code .data.
587
- # In case of fatal error returns { fatal_error: "the error description", code: nil, message: nil, data: '' }
588
- # @example
589
- # resp = @http.patch(Requests::Customer.unrelease_account)
590
- ######################################################
591
- def patch(*arguments)
592
- begin
593
- path, data, headers_t = manage_request(*arguments)
594
- @start_time = Time.now if @start_time.nil?
595
- if arguments.size > 0 and arguments[0].kind_of?(Hash)
596
- arg = arguments[0]
597
- if @use_mocks and arg.kind_of?(Hash) and arg.keys.include?(:mock_response)
598
- data = ""
599
- if arg[:mock_response].keys.include?(:data)
600
- data = arg[:mock_response][:data]
601
- if data.kind_of?(Hash) #to json
602
- begin
603
- require "json"
604
- data = data.to_json
605
- rescue
606
- @logger.fatal "There was a problem converting to json: #{data}"
607
- end
608
- end
609
- end
610
- @logger.warn "Pay attention!!! This is a mock response:"
611
- @start_time_net = Time.now if @start_time_net.nil?
612
- manage_response(arg[:mock_response], data.to_s)
613
- return @response
614
- end
615
- end
616
-
617
- begin
618
- @start_time_net = Time.now if @start_time_net.nil?
619
- resp = @http.patch(path, data, headers_t)
620
- data = resp.body
621
- rescue Exception => stack
622
- @logger.warn stack
623
- @logger.warn "The connection seems to be closed in the host machine. Trying to reconnect"
624
- @http.finish()
625
- @http.start()
626
- @start_time_net = Time.now if @start_time_net.nil?
627
- resp, data = @http.patch(path, data, headers_t)
628
- end
629
- manage_response(resp, data)
630
- if @auto_redirect and @response[:code].to_i >= 300 and @response[:code].to_i < 400 and @response.include?(:location)
631
- if @num_redirects <= 30
632
- @num_redirects += 1
633
- current_server = "http"
634
- current_server += "s" if @ssl == true
635
- current_server += "://#{@host}"
636
- location = @response[:location].gsub(current_server, "")
637
- @logger.info "(#{@num_redirects}) Redirecting NiceHttp to #{location}"
638
- get(location)
639
- else
640
- @logger.fatal "(#{@num_redirects}) Maximum number of redirections for a single request reached. Be sure everything is correct, it seems there is a non ending loop"
641
- @num_redirects = 0
642
- end
643
- else
644
- @num_redirects = 0
645
- end
646
- return @response
647
- rescue Exception => stack
648
- @logger.fatal stack
649
- return {fatal_error: stack.to_s, code: nil, message: nil, data: ""}
650
- end
651
- end
652
-
653
- ######################################################
654
- # Delete an existing resource
655
- # @param arg [Hash] containing at least key :path
656
- # @param arg [String] the path
657
- #
658
- # @return [Hash] response
659
- # Including at least the symbol keys:
660
- # :data = the response data body.
661
- # :message = plain text response.
662
- # :code = code response (200=ok,500=wrong...).
663
- # All keys in response are lowercase.
664
- # data, message and code can also be accessed as attributes like .message .code .data.
665
- # In case of fatal error returns { fatal_error: "the error description", code: nil, message: nil, data: '' }
666
- # @example
667
- # resp = @http.delete(Requests::Customer.remove_session)
668
- # assert resp.code == 204
669
- ######################################################
670
- def delete(argument)
671
- begin
672
- if argument.kind_of?(String)
673
- argument = {:path => argument}
674
- end
675
- path, data, headers_t = manage_request(argument)
676
- @start_time = Time.now if @start_time.nil?
677
- if argument.kind_of?(Hash)
678
- arg = argument
679
- if @use_mocks and arg.kind_of?(Hash) and arg.keys.include?(:mock_response)
680
- data = ""
681
- if arg[:mock_response].keys.include?(:data)
682
- data = arg[:mock_response][:data]
683
- if data.kind_of?(Hash) #to json
684
- begin
685
- require "json"
686
- data = data.to_json
687
- rescue
688
- @logger.fatal "There was a problem converting to json: #{data}"
689
- end
690
- end
691
- end
692
- @logger.warn "Pay attention!!! This is a mock response:"
693
- @start_time_net = Time.now if @start_time_net.nil?
694
- manage_response(arg[:mock_response], data.to_s)
695
- return @response
696
- end
697
- end
698
-
699
- begin
700
- @start_time_net = Time.now if @start_time_net.nil?
701
- resp = @http.delete(path, headers_t)
702
- data = resp.body
703
- rescue Exception => stack
704
- @logger.warn stack
705
- @logger.warn "The connection seems to be closed in the host machine. Trying to reconnect"
706
- @http.finish()
707
- @http.start()
708
- @start_time_net = Time.now if @start_time_net.nil?
709
- resp, data = @http.delete(path)
710
- end
711
- manage_response(resp, data)
712
-
713
- return @response
714
- rescue Exception => stack
715
- @logger.fatal stack
716
- return {fatal_error: stack.to_s, code: nil, message: nil, data: ""}
717
- end
718
- end
719
-
720
- ######################################################
721
- # Implementation of the http HEAD method.
722
- # Asks for the response identical to the one that would correspond to a GET request, but without the response body.
723
- # This is useful for retrieving meta-information written in response headers, without having to transport the entire content.
724
- # @param arg [Hash] containing at least key :path
725
- # @param arg [String] the path
726
- #
727
- # @return [Hash] response
728
- # Including at least the symbol keys:
729
- # :message = plain text response.
730
- # :code = code response (200=ok,500=wrong...).
731
- # All keys in response are lowercase.
732
- # message and code can also be accessed as attributes like .message .code.
733
- # In case of fatal error returns { fatal_error: "the error description", code: nil, message: nil }
734
- ######################################################
735
- def head(argument)
736
- begin
737
- if argument.kind_of?(String)
738
- argument = {:path => argument}
739
- end
740
- path, data, headers_t = manage_request(argument)
741
- @start_time = Time.now if @start_time.nil?
742
- if argument.kind_of?(Hash)
743
- arg = argument
744
- if @use_mocks and arg.kind_of?(Hash) and arg.keys.include?(:mock_response)
745
- @logger.warn "Pay attention!!! This is a mock response:"
746
- @start_time_net = Time.now if @start_time_net.nil?
747
- manage_response(arg[:mock_response], "")
748
- return @response
749
- end
750
- end
751
-
752
- begin
753
- @start_time_net = Time.now if @start_time_net.nil?
754
- resp = @http.head(path, headers_t)
755
- data = resp.body
756
- rescue Exception => stack
757
- @logger.warn stack
758
- @logger.warn "The connection seems to be closed in the host machine. Trying to reconnect"
759
- @http.finish()
760
- @http.start()
761
- @start_time_net = Time.now if @start_time_net.nil?
762
- resp, data = @http.head(path)
763
- end
764
- manage_response(resp, data)
765
- return @response
766
- rescue Exception => stack
767
- @logger.fatal stack
768
- return {fatal_error: stack.to_s, code: nil, message: nil}
769
- end
770
- end
771
-
772
- ######################################################
773
- # It will send the request depending on the :method declared on the request hash
774
- # Take a look at https://github.com/MarioRuiz/Request-Hash
775
- #
776
- # @param request_hash [Hash] containing at least key :path and :method. The methods that are accepted are: :get, :head, :post, :put, :delete, :patch
777
- #
778
- # @return [Hash] response
779
- # Including at least the symbol keys:
780
- # :data = the response data body.
781
- # :message = plain text response.
782
- # :code = code response (200=ok,500=wrong...).
783
- # All keys in response are lowercase.
784
- # data, message and code can also be accessed as attributes like .message .code .data.
785
- # In case of fatal error returns { fatal_error: "the error description", code: nil, message: nil, data: '' }
786
- # @example
787
- # resp = @http.send_request Requests::Customer.remove_session
788
- # assert resp.code == 204
789
- ######################################################
790
- def send_request(request_hash)
791
- unless request_hash.is_a?(Hash) and request_hash.key?(:method) and request_hash.key?(:path) and
792
- request_hash[:method].is_a?(Symbol) and
793
- [:get, :head, :post, :put, :delete, :patch].include?(request_hash[:method])
794
-
795
- message = "send_request: it needs to be supplied a Request Hash that includes a :method and :path. "
796
- message += "Supported methods: :get, :head, :post, :put, :delete, :patch"
797
- @logger.fatal message
798
- return {fatal_error: message, code: nil, message: nil}
799
- else
800
- case request_hash[:method]
801
- when :get
802
- resp = get request_hash
803
- when :post
804
- resp = post request_hash
805
- when :head
806
- resp = head request_hash
807
- when :put
808
- resp = put request_hash
809
- when :delete
810
- resp = delete request_hash
811
- when :patch
812
- resp = patch request_hash
813
- end
814
- return resp
815
- end
816
-
817
-
818
- end
819
-
820
301
  ######################################################
821
302
  # Close HTTP connection
822
303
  ######################################################
@@ -854,412 +335,5 @@ class NiceHttp
854
335
  self.class.active -= 1
855
336
  end
856
337
 
857
- ######################################################
858
- # private method to manage Request
859
- # input:
860
- # 3 args: path, data, headers
861
- # 1 arg: Hash containg at least keys :path and :data
862
- # In case :data not supplied and :data_examples array supplied, it will be taken the first example as :data.
863
- # output:
864
- # path, data, headers
865
- ######################################################
866
- def manage_request(*arguments)
867
- require "json"
868
- begin
869
- content_type_included = false
870
- path = ""
871
- data = ""
872
-
873
- @response = Hash.new()
874
- headers_t = @headers.dup()
875
- cookies_to_set_str = ""
876
- if arguments.size == 3
877
- path = arguments[0]
878
- elsif arguments.size == 1 and arguments[0].kind_of?(Hash)
879
- path = arguments[0][:path]
880
- elsif arguments.size == 1 and arguments[0].kind_of?(String)
881
- path = arguments[0].to_s()
882
- end
883
- path = (@prepath + path).gsub('//','/') unless path.nil? or path.start_with?('http:') or path.start_with?('https:')
884
- @cookies.each { |cookie_path, cookies_hash|
885
- cookie_path = "" if cookie_path == "/"
886
- path_to_check = path
887
- if path == "/" or path[-1] != "/"
888
- path_to_check += "/"
889
- end
890
- if path_to_check.scan(/^#{cookie_path}\//).size > 0
891
- cookies_hash.each { |key, value|
892
- cookies_to_set_str += "#{key}=#{value}; "
893
- }
894
- end
895
- }
896
- headers_t["Cookie"] = cookies_to_set_str
897
-
898
- method_s = caller[0].to_s().scan(/:in `(.*)'/).join
899
-
900
- if arguments.size == 3
901
- data = arguments[1]
902
- if arguments[2].kind_of?(Hash)
903
- headers_t.merge!(arguments[2])
904
- end
905
- elsif arguments.size == 1 and arguments[0].kind_of?(Hash)
906
- if arguments[0][:data].nil?
907
- if arguments[0].keys.include?(:data)
908
- data = ""
909
- elsif arguments[0].keys.include?(:data_examples) and
910
- arguments[0][:data_examples].kind_of?(Array)
911
- data = arguments[0][:data_examples][0] #the first example by default
912
- else
913
- data = ""
914
- end
915
- else
916
- data = arguments[0][:data]
917
- end
918
- if arguments[0].include?(:headers)
919
- headers_t.merge!(arguments[0][:headers])
920
- end
921
-
922
- if headers_t["Content-Type"].to_s() == "" and headers_t["content-type"].to_s() == "" and
923
- headers_t[:"content-type"].to_s() == "" and headers_t[:"Content-Type"].to_s() == ""
924
- content_type_included = false
925
- elsif headers_t["content-type"].to_s() != ""
926
- content_type_included = true
927
- headers_t["Content-Type"] = headers_t["content-type"]
928
- elsif headers_t[:"content-type"].to_s() != ""
929
- content_type_included = true
930
- headers_t["Content-Type"] = headers_t[:"content-type"]
931
- headers_t.delete(:"content-type")
932
- elsif headers_t[:"Content-Type"].to_s() != ""
933
- content_type_included = true
934
- headers_t["Content-Type"] = headers_t[:"Content-Type"]
935
- headers_t.delete(:"Content-Type")
936
- elsif headers_t["Content-Type"].to_s() != ""
937
- content_type_included = true
938
- end
939
- if !content_type_included and data.kind_of?(Hash)
940
- headers_t["Content-Type"] = "application/json"
941
- content_type_included = true
942
- end
943
- # to be backwards compatible since before was :values
944
- if arguments[0].include?(:values) and !arguments[0].include?(:values_for)
945
- arguments[0][:values_for] = arguments[0][:values]
946
- end
947
- if content_type_included and (!headers_t["Content-Type"][/text\/xml/].nil? or
948
- !headers_t["Content-Type"]["application/soap+xml"].nil? or
949
- !headers_t["Content-Type"][/application\/jxml/].nil?)
950
- if arguments[0].include?(:values_for)
951
- arguments[0][:values_for].each { |key, value|
952
- data = NiceHttpUtils.set_value_xml_tag(key.to_s(), data, value.to_s(), true)
953
- }
954
- end
955
- elsif content_type_included and !headers_t["Content-Type"][/application\/json/].nil? and data.to_s() != ""
956
- require "json"
957
- if data.kind_of?(String)
958
- if arguments[0].include?(:values_for)
959
- arguments[0][:values_for].each { |key, value|
960
- data.gsub!(/(( *|^)"?#{key.to_s()}"? *: *")(.*)(" *, *$)/, '\1' + value + '\4') # "key":"value", or key:"value",
961
- data.gsub!(/(( *|^)"?#{key.to_s()}"? *: *")(.*)(" *$)/, '\1' + value + '\4') # "key":"value" or key:"value"
962
- data.gsub!(/(( *|^)"?#{key.to_s()}"? *: *[^"])([^"].*)([^"] *, *$)/, '\1' + value + '\4') # "key":456, or key:456,
963
- data.gsub!(/(( *|^)"?#{key.to_s()}"? *: *[^"])([^"].*)([^"] * *$)/, '\1' + value + '\4') # "key":456 or key:456
964
- }
965
- end
966
- elsif data.kind_of?(Hash)
967
- data_n = Hash.new()
968
- data.each { |key, value|
969
- data_n[key.to_s()] = value
970
- }
971
- if arguments[0].include?(:values_for)
972
- #req[:values_for][:loginName] or req[:values_for]["loginName"]
973
- new_values_hash = Hash.new()
974
- arguments[0][:values_for].each { |kv, vv|
975
- if data_n.keys.include?(kv.to_s())
976
- new_values_hash[kv.to_s()] = vv
977
- end
978
- }
979
- data_n.merge!(new_values_hash)
980
- end
981
- data = data_n.to_json()
982
- elsif data.kind_of?(Array)
983
- data_arr = Array.new()
984
- data.each_with_index { |row, indx|
985
- unless row.kind_of?(Hash)
986
- @logger.fatal("Wrong format on request application/json, be sure is a Hash, Array of Hashes or JSON string")
987
- return :error, :error, :error
988
- end
989
- data_n = Hash.new()
990
- row.each { |key, value|
991
- data_n[key.to_s()] = value
992
- }
993
- if arguments[0].include?(:values_for)
994
- #req[:values_for][:loginName] or req[:values_for]["loginName"]
995
- new_values_hash = Hash.new()
996
- if arguments[0][:values_for].kind_of?(Hash) #values[:mykey][3]
997
- arguments[0][:values_for].each { |kv, vv|
998
- if data_n.keys.include?(kv.to_s()) and !vv[indx].nil?
999
- new_values_hash[kv.to_s()] = vv[indx]
1000
- end
1001
- }
1002
- elsif arguments[0][:values_for].kind_of?(Array) #values[5][:mykey]
1003
- if !arguments[0][:values_for][indx].nil?
1004
- arguments[0][:values_for][indx].each { |kv, vv|
1005
- if data_n.keys.include?(kv.to_s())
1006
- new_values_hash[kv.to_s()] = vv
1007
- end
1008
- }
1009
- end
1010
- else
1011
- @logger.fatal("Wrong format on request application/json when supplying values, the data is an array of Hashes but the values supplied are not")
1012
- return :error, :error, :error
1013
- end
1014
- data_n.merge!(new_values_hash)
1015
- end
1016
- data_arr.push(data_n)
1017
- }
1018
- data = data_arr.to_json()
1019
- else
1020
- @logger.fatal("Wrong format on request application/json, be sure is a Hash, Array of Hashes or JSON string")
1021
- return :error, :error, :error
1022
- end
1023
- elsif content_type_included and arguments[0].include?(:values_for)
1024
- if arguments[0][:values_for].kind_of?(Hash) and arguments[0][:values_for].keys.size > 0
1025
- if !headers_t.nil? and headers_t.kind_of?(Hash) and headers_t["Content-Type"] != "application/x-www-form-urlencoded" and headers_t["content-type"] != "application/x-www-form-urlencoded"
1026
- @logger.warn(":values_for key given without a valid content-type or data for request. No values modified on the request")
1027
- end
1028
- end
1029
- end
1030
- elsif arguments.size == 1 and arguments[0].kind_of?(String)
1031
- #path=arguments[0].to_s()
1032
- data = ""
1033
- else
1034
- @logger.fatal("Invalid number of arguments or wrong arguments in #{method_s}")
1035
- return :error, :error, :error
1036
- end
1037
- if headers_t.keys.include?("Content-Type") and !headers_t["Content-Type"]["multipart/form-data"].nil? and headers_t["Content-Type"] != ["multipart/form-data"] #only for the case raw multipart request
1038
- encoding = "UTF-8"
1039
- data_s = ""
1040
- else
1041
- encoding = data.to_s().scan(/encoding='(.*)'/i).join
1042
- if encoding.to_s() == ""
1043
- encoding = data.to_s().scan(/charset='(.*)'/i).join
1044
- end
1045
- if encoding.to_s() == "" and headers_t.include?("Content-Type")
1046
- encoding = headers_t["Content-Type"].scan(/charset='?(.*)'?/i).join
1047
- if encoding.to_s() == ""
1048
- encoding = headers_t["Content-Type"].scan(/encoding='?(.*)'?/i).join
1049
- end
1050
- end
1051
-
1052
- begin
1053
- data_s = JSON.pretty_generate(JSON.parse(data))
1054
- rescue
1055
- data_s = data
1056
- end
1057
- data_s = data_s.to_s().gsub("<", "&lt;")
1058
- end
1059
- if headers_t.keys.include?("Accept-Encoding")
1060
- headers_t["Accept-Encoding"].gsub!("gzip", "") #removed so the response is in plain text
1061
- end
1062
-
1063
- headers_ts = ""
1064
- headers_t.each { |key, val| headers_ts += key.to_s + ":" + val.to_s() + ", " }
1065
- message = "#{method_s} REQUEST: \npath= " + path.to_s() + "\n"
1066
- message += "headers= " + headers_ts.to_s() + "\n"
1067
- message += "data= " + data_s.to_s() + "\n"
1068
- message = @message_server + "\n" + message
1069
- if path.to_s().scan(/^https?:\/\//).size > 0 and path.to_s().scan(/^https?:\/\/#{@host}/).size == 0
1070
- # the path is for another server than the current
1071
- else
1072
- self.class.last_request = message
1073
- @logger.info(message)
1074
- end
1075
-
1076
- if data.to_s() != "" and encoding.to_s().upcase != "UTF-8" and encoding != ""
1077
- data = data.to_s().encode(encoding, "UTF-8")
1078
- end
1079
- return path, data, headers_t
1080
- rescue Exception => stack
1081
- @logger.fatal(stack)
1082
- @logger.fatal("manage_request Error on method #{method_s} . path:#{path.to_s()}. data:#{data.to_s()}. headers:#{headers_t.to_s()}")
1083
- return :error
1084
- end
1085
- end
1086
-
1087
- ######################################################
1088
- # private method to manage Response
1089
- # input:
1090
- # resp
1091
- # data
1092
- # output:
1093
- # @response updated
1094
- ######################################################
1095
- def manage_response(resp, data)
1096
- require "json"
1097
- begin
1098
- if @start_time.kind_of?(Time)
1099
- @response[:time_elapsed_total] = Time.now - @start_time
1100
- @start_time = nil
1101
- else
1102
- @response[:time_elapsed_total] = nil
1103
- end
1104
- if @start_time_net.kind_of?(Time)
1105
- @response[:time_elapsed] = Time.now - @start_time_net
1106
- @start_time_net = nil
1107
- else
1108
- @response[:time_elapsed] = nil
1109
- end
1110
- begin
1111
- # this is to be able to access all keys as symbols
1112
- new_resp = Hash.new()
1113
- resp.each { |key, value|
1114
- if key.kind_of?(String)
1115
- new_resp[key.to_sym] = value
1116
- end
1117
- }
1118
- new_resp.each { |key, value|
1119
- resp[key] = value
1120
- }
1121
- rescue
1122
- end
1123
- #for mock_responses to be able to add outside of the header like content-type for example
1124
- if resp.kind_of?(Hash) and !resp.has_key?(:header)
1125
- resp[:header] = {}
1126
- end
1127
- if resp.kind_of?(Hash)
1128
- resp.each { |k, v|
1129
- if k != :code and k != :message and k != :data and k != :'set-cookie' and k != :header
1130
- resp[:header][k] = v
1131
- end
1132
- }
1133
- resp[:header].each { |k, v|
1134
- resp.delete(k) if resp.has_key?(k)
1135
- }
1136
- end
1137
-
1138
- method_s = caller[0].to_s().scan(/:in `(.*)'/).join
1139
- if resp.header.kind_of?(Hash) and (resp.header["content-type"].to_s() == "application/x-deflate" or resp.header[:"content-type"].to_s() == "application/x-deflate")
1140
- data = Zlib::Inflate.inflate(data)
1141
- end
1142
- encoding_response = ""
1143
- if resp.header.kind_of?(Hash) and (resp.header["content-type"].to_s() != "" or resp.header[:"content-type"].to_s() != "")
1144
- encoding_response = resp.header["content-type"].scan(/;charset=(.*)/i).join if resp.header.has_key?("content-type")
1145
- encoding_response = resp.header[:"content-type"].scan(/;charset=(.*)/i).join if resp.header.has_key?(:"content-type")
1146
- end
1147
- if encoding_response.to_s() == ""
1148
- encoding_response = "UTF-8"
1149
- end
1150
-
1151
- if encoding_response.to_s() != "" and encoding_response.to_s().upcase != "UTF-8"
1152
- data.encode!("UTF-8", encoding_response.to_s())
1153
- end
1154
-
1155
- if encoding_response != "" and encoding_response.to_s().upcase != "UTF-8"
1156
- @response[:message] = resp.message.to_s().encode("UTF-8", encoding_response.to_s())
1157
- #todo: response data in here for example is convert into string, verify if that is correct or needs to maintain the original data type (hash, array...)
1158
- resp.each { |key, val| @response[key.to_sym] = val.to_s().encode("UTF-8", encoding_response.to_s()) }
1159
- else
1160
- @response[:message] = resp.message
1161
- resp.each { |key, val|
1162
- @response[key.to_sym] = val
1163
- }
1164
- end
1165
-
1166
- if !defined?(Net::HTTP::Post::Multipart) or (defined?(Net::HTTP::Post::Multipart) and !data.kind_of?(Net::HTTP::Post::Multipart))
1167
- @response[:data] = data
1168
- else
1169
- @response[:data] = ""
1170
- end
1171
-
1172
- @response[:code] = resp.code
1173
-
1174
- unless @response.nil?
1175
- message = "\nRESPONSE: \n" + @response[:code].to_s() + ":" + @response[:message].to_s()
1176
- #if @debug
1177
- self.class.last_response = message if @debug
1178
- @response.each { |key, value|
1179
- if value.to_s() != ""
1180
- value_orig = value
1181
- if key.kind_of?(Symbol)
1182
- if key == :code or key == :data or key == :header or key == :message
1183
- if key == :data
1184
- begin
1185
- JSON.parse(value_orig)
1186
- data_s = JSON.pretty_generate(JSON.parse(value_orig))
1187
- rescue
1188
- data_s = value_orig
1189
- end
1190
- if @debug
1191
- self.class.last_response += "\nresponse." + key.to_s() + " = '" + data_s.gsub("<", "&lt;") + "'\n"
1192
- end
1193
- if value_orig != value
1194
- message += "\nresponse." + key.to_s() + " = '" + value.gsub("<", "&lt;") + "'\n"
1195
- else
1196
- message += "\nresponse." + key.to_s() + " = '" + data_s.gsub("<", "&lt;") + "'\n"
1197
- end
1198
- else
1199
- if @debug
1200
- self.class.last_response += "\nresponse." + key.to_s() + " = '" + value.to_s().gsub("<", "&lt;") + "'"
1201
- message += "\nresponse." + key.to_s() + " = '" + value.to_s().gsub("<", "&lt;") + "'"
1202
- end
1203
- end
1204
- else
1205
- if @debug
1206
- self.class.last_response += "\nresponse[:" + key.to_s() + "] = '" + value.to_s().gsub("<", "&lt;") + "'"
1207
- end
1208
- message += "\nresponse[:" + key.to_s() + "] = '" + value.to_s().gsub("<", "&lt;") + "'"
1209
- end
1210
- elsif !@response.include?(key.to_sym)
1211
- if @debug
1212
- self.class.last_response += "\nresponse['" + key.to_s() + "'] = '" + value.to_s().gsub("<", "&lt;") + "'"
1213
- end
1214
- message += "\nresponse['" + key.to_s() + "'] = '" + value.to_s().gsub("<", "&lt;") + "'"
1215
- end
1216
- end
1217
- }
1218
- #end
1219
- @logger.info message
1220
- if @response.kind_of?(Hash)
1221
- if @response.keys.include?(:requestid)
1222
- @headers["requestId"] = @response[:requestid]
1223
- self.class.request_id = @response[:requestid]
1224
- @logger.info "requestId was found on the response header and it has been added to the headers for the next request"
1225
- end
1226
- end
1227
- end
1228
-
1229
- if resp[:'set-cookie'].to_s() != ""
1230
- if resp.kind_of?(Hash) #mock_response
1231
- cookies_to_set = resp[:'set-cookie'].to_s().split(", ")
1232
- else #Net::Http
1233
- cookies_to_set = resp.get_fields("set-cookie")
1234
- end
1235
- cookies_to_set.each { |cookie|
1236
- cookie_pair = cookie.split("; ")[0].split("=")
1237
- cookie_path = cookie.scan(/; path=([^;]+)/i).join
1238
- @cookies[cookie_path] = Hash.new() unless @cookies.keys.include?(cookie_path)
1239
- @cookies[cookie_path][cookie_pair[0]] = cookie_pair[1]
1240
- }
1241
-
1242
- @logger.info "set-cookie added to Cookie header as required"
1243
-
1244
- if @headers.has_key?("X-CSRFToken")
1245
- csrftoken = resp[:"set-cookie"].to_s().scan(/csrftoken=([\da-z]+);/).join
1246
- if csrftoken.to_s() != ""
1247
- @headers["X-CSRFToken"] = csrftoken
1248
- @logger.info "X-CSRFToken exists on headers and has been overwritten"
1249
- end
1250
- else
1251
- csrftoken = resp[:"set-cookie"].to_s().scan(/csrftoken=([\da-z]+);/).join
1252
- if csrftoken.to_s() != ""
1253
- @headers["X-CSRFToken"] = csrftoken
1254
- @logger.info "X-CSRFToken added to header as required"
1255
- end
1256
- end
1257
- end
1258
- rescue Exception => stack
1259
- @logger.fatal stack
1260
- @logger.fatal "manage_response Error on method #{method_s} "
1261
- end
1262
- end
1263
-
1264
338
  private :manage_request, :manage_response
1265
339
  end
metadata CHANGED
@@ -1,55 +1,55 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: nice_http
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.4.1
4
+ version: 1.5.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Mario Ruiz
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-02-14 00:00:00.000000000 Z
11
+ date: 2019-02-15 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: nice_hash
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - ">="
18
- - !ruby/object:Gem::Version
19
- version: 1.9.0
20
17
  - - "~>"
21
18
  - !ruby/object:Gem::Version
22
19
  version: '1.9'
20
+ - - ">="
21
+ - !ruby/object:Gem::Version
22
+ version: 1.9.0
23
23
  type: :runtime
24
24
  prerelease: false
25
25
  version_requirements: !ruby/object:Gem::Requirement
26
26
  requirements:
27
- - - ">="
28
- - !ruby/object:Gem::Version
29
- version: 1.9.0
30
27
  - - "~>"
31
28
  - !ruby/object:Gem::Version
32
29
  version: '1.9'
30
+ - - ">="
31
+ - !ruby/object:Gem::Version
32
+ version: 1.9.0
33
33
  - !ruby/object:Gem::Dependency
34
34
  name: rspec
35
35
  requirement: !ruby/object:Gem::Requirement
36
36
  requirements:
37
- - - ">="
38
- - !ruby/object:Gem::Version
39
- version: 3.8.0
40
37
  - - "~>"
41
38
  - !ruby/object:Gem::Version
42
39
  version: '3.8'
40
+ - - ">="
41
+ - !ruby/object:Gem::Version
42
+ version: 3.8.0
43
43
  type: :development
44
44
  prerelease: false
45
45
  version_requirements: !ruby/object:Gem::Requirement
46
46
  requirements:
47
- - - ">="
48
- - !ruby/object:Gem::Version
49
- version: 3.8.0
50
47
  - - "~>"
51
48
  - !ruby/object:Gem::Version
52
49
  version: '3.8'
50
+ - - ">="
51
+ - !ruby/object:Gem::Version
52
+ version: 3.8.0
53
53
  - !ruby/object:Gem::Dependency
54
54
  name: coveralls
55
55
  requirement: !ruby/object:Gem::Requirement
@@ -104,7 +104,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
104
104
  - !ruby/object:Gem::Version
105
105
  version: '0'
106
106
  requirements: []
107
- rubygems_version: 3.0.1
107
+ rubyforge_project:
108
+ rubygems_version: 2.7.6
108
109
  signing_key:
109
110
  specification_version: 4
110
111
  summary: NiceHttp -- simplest library for accessing and testing HTTP and REST resources.