vcr 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.document +5 -0
- data/.gitignore +22 -0
- data/LICENSE +20 -0
- data/README.rdoc +156 -0
- data/Rakefile +60 -0
- data/VERSION +1 -0
- data/features/fixtures/vcr_cassettes/1.8.6/cucumber_tags/replay_cassette1.yml +43 -0
- data/features/fixtures/vcr_cassettes/1.8.6/cucumber_tags/replay_cassette2.yml +45 -0
- data/features/fixtures/vcr_cassettes/1.8.6/nested_replay_cassette.yml +23 -0
- data/features/fixtures/vcr_cassettes/1.8.6/not_the_real_response.yml +43 -0
- data/features/fixtures/vcr_cassettes/1.8.7/cucumber_tags/replay_cassette1.yml +43 -0
- data/features/fixtures/vcr_cassettes/1.8.7/cucumber_tags/replay_cassette2.yml +45 -0
- data/features/fixtures/vcr_cassettes/1.8.7/nested_replay_cassette.yml +23 -0
- data/features/fixtures/vcr_cassettes/1.8.7/not_the_real_response.yml +43 -0
- data/features/fixtures/vcr_cassettes/1.9.1/cucumber_tags/replay_cassette1.yml +43 -0
- data/features/fixtures/vcr_cassettes/1.9.1/cucumber_tags/replay_cassette2.yml +61 -0
- data/features/fixtures/vcr_cassettes/1.9.1/nested_replay_cassette.yml +31 -0
- data/features/fixtures/vcr_cassettes/1.9.1/not_the_real_response.yml +43 -0
- data/features/record_response.feature +55 -0
- data/features/replay_recorded_response.feature +53 -0
- data/features/step_definitions/vcr_steps.rb +88 -0
- data/features/support/env.rb +55 -0
- data/lib/vcr.rb +48 -0
- data/lib/vcr/cassette.rb +89 -0
- data/lib/vcr/config.rb +19 -0
- data/lib/vcr/cucumber_tags.rb +38 -0
- data/lib/vcr/fake_web_extensions.rb +18 -0
- data/lib/vcr/net_http_extensions.rb +39 -0
- data/lib/vcr/recorded_response.rb +4 -0
- data/spec/cassette_spec.rb +185 -0
- data/spec/config_spec.rb +27 -0
- data/spec/cucumber_tags_spec.rb +71 -0
- data/spec/fake_web_extensions_spec.rb +26 -0
- data/spec/fixtures/1.8.6/cassette_spec/example.yml +78 -0
- data/spec/fixtures/1.8.7/cassette_spec/example.yml +78 -0
- data/spec/fixtures/1.9.1/cassette_spec/example.yml +77 -0
- data/spec/net_http_extensions_spec.rb +40 -0
- data/spec/recorded_response_spec.rb +25 -0
- data/spec/spec.opts +2 -0
- data/spec/spec_helper.rb +22 -0
- data/spec/support/temp_cache_dir.rb +16 -0
- data/spec/vcr_spec.rb +95 -0
- metadata +154 -0
data/.document
ADDED
data/.gitignore
ADDED
data/LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2009 Myron Marston
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.rdoc
ADDED
@@ -0,0 +1,156 @@
|
|
1
|
+
= VCR
|
2
|
+
|
3
|
+
VCR provides helpers to record HTTP requests for URIs that are not registered with fakeweb, and replay them later.
|
4
|
+
It provides built-in support for cucumber, but works with any ruby testing framework.
|
5
|
+
|
6
|
+
== Installation
|
7
|
+
|
8
|
+
gem install vcr
|
9
|
+
|
10
|
+
== Background
|
11
|
+
|
12
|
+
This README assumes you are familiar with FakeWeb; if not, please checkout the {README}[http://github.com/chrisk/fakeweb/blob/master/README.rdoc].
|
13
|
+
|
14
|
+
VCR was inspired by {NetRecorder}[http://github.com/chrisyoung/netrecorder], but was designed from the ground up to support
|
15
|
+
localized recording and replaying, rather than the global recording and replaying of NetRecorder.
|
16
|
+
|
17
|
+
== Cassettes
|
18
|
+
|
19
|
+
Cassettes are central to the way VCR works. They are a similar to VHS cassettes--your library of cassettes
|
20
|
+
is your library of previously recorded responses that can be replayed. When you create a cassette, it does
|
21
|
+
the following:
|
22
|
+
|
23
|
+
* It loads the previously recorded responses from the cache file corresponding to the cassette name.
|
24
|
+
* It register these responses with fakeweb (depending on the cassette's :record option--see below)
|
25
|
+
* It sets the <tt>FakeWeb.allow_net_connect</tt> setting based on the cassette's :record option.
|
26
|
+
|
27
|
+
While a cassette is active, any HTTP requests to a URL of a previously recorded responses will use get
|
28
|
+
the recorded response. New HTTP requests (i.e. HTTP requests that have not been previously recorded)
|
29
|
+
will be recorded to the same cache file, depending on your :record option. When you destroy a cassette,
|
30
|
+
it does the following:
|
31
|
+
|
32
|
+
* It saves all of the recorded responses (both old and new) to a cached yml file corresponding to the cassette name.
|
33
|
+
* It removes the registrations it made with fakeweb, to prevent "leakage" into other tests.
|
34
|
+
* It reverts the <tt>FakeWeb.allow_net_connect</tt> back to whatever it was before the cassette was created.
|
35
|
+
|
36
|
+
== Record modes
|
37
|
+
|
38
|
+
VCR supports 3 record modes, which configures when it records new responses. You can set a default
|
39
|
+
record mode in your configuration (see below) and a per-cassette record mode when creating a cassette. The record
|
40
|
+
modes are:
|
41
|
+
|
42
|
+
* :all - This will cause VCR to re-record all HTTP requests that occur while the cassette is the current one.
|
43
|
+
When the cassette is created, it will not register any of the cached responses with fakeweb.
|
44
|
+
<tt>FakeWeb.allow_net_connect</tt> will be set to true, so it can record the requests.
|
45
|
+
* :none - This will prevent VCR from recording, or even allowing, any new HTTP requests while the cassette is the current one.
|
46
|
+
The previously recorded responses will be registered with fakeweb. <tt>FakeWeb.allow_net_connect</tt> will be set to
|
47
|
+
false, so that no new HTTP connections are allowed.
|
48
|
+
* :unregistered - This will use the previously recorded responses, and record any new requests that are not registered with
|
49
|
+
fakeweb. The previously recorded responses will be registered with fakeweb. <tt>FakeWeb.allow_net_connect</tt> will be
|
50
|
+
set to true, so that VCR will record any new HTTP requests within the cassette.
|
51
|
+
|
52
|
+
Note that :none and :unregistered will usually at the same. The difference is when your code changes and
|
53
|
+
it makes a new HTTP request that wasn't made when the cassette was first recorded. With :none, you would
|
54
|
+
get an error from FakeWeb (since allow_net_connect is set to false). With :unregistered, the new response
|
55
|
+
would get saved in the cassette's yaml file, and automatically get used in the future.
|
56
|
+
|
57
|
+
== Configuration
|
58
|
+
|
59
|
+
# Set the default allow_net_connect option--usually you'll want this off.
|
60
|
+
# You don't usually want your test suite to make HTTP connections, do you?
|
61
|
+
FakeWeb.allow_net_connect = false
|
62
|
+
|
63
|
+
VCR.config do |c|
|
64
|
+
# the cache_dir is where the cassette yml files will be saved.
|
65
|
+
c.cache_dir = File.join(Rails.root, 'features', 'fixtures', 'vcr_cassettes')
|
66
|
+
|
67
|
+
# this record mode will be used for any cassette you create without specifying a record mode.
|
68
|
+
c.default_cassette_record_mode = :none
|
69
|
+
end
|
70
|
+
|
71
|
+
This can go pretty much wherever, as long as this code is run before your tests, specs or scenarios.
|
72
|
+
|
73
|
+
== Usage with your favorite test/spec framework
|
74
|
+
|
75
|
+
VCR can easily be used with any ruby test/spec framework. Usually, you'll want to use <tt>VCR.with_cassette</tt>:
|
76
|
+
|
77
|
+
VCR.with_cassette('geocoding/Seattle, WA', :record => :unregistered) do
|
78
|
+
# do something that causes an HTTP request.
|
79
|
+
end
|
80
|
+
|
81
|
+
Alternately, you can create and destroy the cassette with individual method calls from setup/before and teardown/after:
|
82
|
+
|
83
|
+
describe "Something that makes an HTTP request" do
|
84
|
+
before(:each) do
|
85
|
+
VCR.create_cassette!('geocoding/Seattle, WA', :record => :unregistered)
|
86
|
+
end
|
87
|
+
|
88
|
+
it "should do something that makes an HTTP request"
|
89
|
+
|
90
|
+
after(:each) do
|
91
|
+
VCR.destroy_cassette!
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
In both of these cases, VCR would use the file geocoding/Seattle_WA.yml within the configured
|
96
|
+
cache dir. The :record setting is optional--if you leave it blank, your configured default will be used.
|
97
|
+
|
98
|
+
== Usage with Cucumber
|
99
|
+
|
100
|
+
VCR provides special support for cucumber. You can of course use <tt>VCR.with_cassette</tt> within a step definition,
|
101
|
+
and that's the recommended way for any of your step definitions. But many times I find myself using generic step definitions
|
102
|
+
provided by another library (such as the webrat/capybara web steps generated by cucumber-rails), and I don't want to modify
|
103
|
+
these. VCR provides cucumber tagging support to help in these cases:
|
104
|
+
|
105
|
+
# in a cucumber feature file...
|
106
|
+
@facebook_http_request
|
107
|
+
Scenario: Sign up with facebook connect
|
108
|
+
|
109
|
+
# in features/support/vcr.rb (or some similar support file)
|
110
|
+
VCR.cucumber_tags do |t|
|
111
|
+
t.tags '@facebook_http_request', '@twitter_status_update', :record => :none
|
112
|
+
t.tags '@another_scenario_tag' # the default record mode will be used for this tag.
|
113
|
+
end
|
114
|
+
|
115
|
+
# Note: you'd probably also want to put your VCR config in this file (see above).
|
116
|
+
|
117
|
+
For each of the tags you specify in your cucumber_tags block, VCR will set up the appropriate
|
118
|
+
{Before and After hooks}[http://wiki.github.com/aslakhellesoy/cucumber/hooks] to use a cassette
|
119
|
+
for the entire scenario. The tag (minus the '@') will be used as the cassette name, and it'll
|
120
|
+
go in the cucumber_tags subdirectory of the configured cache dir.
|
121
|
+
|
122
|
+
== Ruby Version Compatibility
|
123
|
+
|
124
|
+
specs.should pass if RUBY_VERSION =~ /^1.(8.6|8.7|9.1)$/
|
125
|
+
|
126
|
+
== Notes, etc.
|
127
|
+
|
128
|
+
* The cassette name determines the name of the cache file for the given cassette. Strings or symbols are fine,
|
129
|
+
and you can include any characters, but spaces and invalid file name characters will be removed
|
130
|
+
before the cassette reads or writes to the file.
|
131
|
+
* You can use a directory separator (i.e. '/') in your cassette names to cause it to use a subdirectory
|
132
|
+
of the cache_dir. The cucumber tagging support uses this.
|
133
|
+
* VCR maintains a simple stack of cassette. This allows you to nest them as deeply as you want.
|
134
|
+
This is particularly useful when you have a cucumber step definition that uses a cassette, and
|
135
|
+
you also want to use a cassette for the entire scenario using the tagging support.
|
136
|
+
|
137
|
+
== Note on Patches/Pull Requests
|
138
|
+
|
139
|
+
* Fork the project.
|
140
|
+
* Make your feature addition or bug fix.
|
141
|
+
* Add tests for it. This is important so I don't break it in a
|
142
|
+
future version unintentionally.
|
143
|
+
* Commit, do not mess with rakefile, version, or history.
|
144
|
+
(if you want to have your own version, that is fine but bump version in a commit by itself I can ignore when I pull)
|
145
|
+
* Send me a pull request. Bonus points for topic branches.
|
146
|
+
|
147
|
+
== Thanks
|
148
|
+
|
149
|
+
* {Aslak Hellesøy}[http://github.com/aslakhellesoy] for {Cucumber}[http://github.com/aslakhellesoy/cucumber].
|
150
|
+
* {Chris Kampmeier}[http://github.com/chrisk] for {FakeWeb}[http://github.com/chrisk/fakeweb].
|
151
|
+
* {Chris Young}[http://github.com/chrisyoung] for {NetRecorder}[http://github.com/chrisyoung/netrecorder], the inspiration
|
152
|
+
for VCR.
|
153
|
+
|
154
|
+
== Copyright
|
155
|
+
|
156
|
+
Copyright (c) 2010 Myron Marston. See LICENSE for details.
|
data/Rakefile
ADDED
@@ -0,0 +1,60 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'rake'
|
3
|
+
|
4
|
+
begin
|
5
|
+
require 'jeweler'
|
6
|
+
Jeweler::Tasks.new do |gem|
|
7
|
+
gem.name = "vcr"
|
8
|
+
gem.summary = %Q{Use VCR to record HTTP responses and replay them using fakeweb.}
|
9
|
+
gem.description = %Q{VCR provides helpers to record HTTP requests for URIs that are not registered with fakeweb, and replay them later. It provides built-in support for cucumber, but works with any ruby testing framework.}
|
10
|
+
gem.email = "myron.marston@gmail.com"
|
11
|
+
gem.homepage = "http://github.com/myronmarston/vcr"
|
12
|
+
gem.authors = ["Myron Marston"]
|
13
|
+
|
14
|
+
gem.add_dependency 'fakeweb', '>= 1.2.8'
|
15
|
+
|
16
|
+
gem.add_development_dependency "rspec", ">= 1.2.9"
|
17
|
+
gem.add_development_dependency "cucumber", ">= 0.6.1"
|
18
|
+
# gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
|
19
|
+
end
|
20
|
+
Jeweler::GemcutterTasks.new
|
21
|
+
rescue LoadError
|
22
|
+
puts "Jeweler (or a dependency) not available. Install it with: gem install jeweler"
|
23
|
+
end
|
24
|
+
|
25
|
+
require 'spec/rake/spectask'
|
26
|
+
Spec::Rake::SpecTask.new(:spec) do |spec|
|
27
|
+
spec.libs << 'lib' << 'spec'
|
28
|
+
spec.spec_files = FileList['spec/**/*_spec.rb']
|
29
|
+
end
|
30
|
+
|
31
|
+
Spec::Rake::SpecTask.new(:rcov) do |spec|
|
32
|
+
spec.libs << 'lib' << 'spec'
|
33
|
+
spec.pattern = 'spec/**/*_spec.rb'
|
34
|
+
spec.rcov = true
|
35
|
+
end
|
36
|
+
|
37
|
+
task :spec => :check_dependencies if defined?(Jeweler)
|
38
|
+
|
39
|
+
begin
|
40
|
+
require 'cucumber/rake/task'
|
41
|
+
Cucumber::Rake::Task.new(:features)
|
42
|
+
|
43
|
+
task :features => :check_dependencies
|
44
|
+
rescue LoadError
|
45
|
+
task :features do
|
46
|
+
abort "Cucumber is not available. In order to run features, you must: sudo gem install cucumber"
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
task :default => [:spec, :features]
|
51
|
+
|
52
|
+
require 'rake/rdoctask'
|
53
|
+
Rake::RDocTask.new do |rdoc|
|
54
|
+
version = File.exist?('VERSION') ? File.read('VERSION') : ""
|
55
|
+
|
56
|
+
rdoc.rdoc_dir = 'rdoc'
|
57
|
+
rdoc.title = "vcr #{version}"
|
58
|
+
rdoc.rdoc_files.include('README*')
|
59
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
60
|
+
end
|
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
0.1.0
|
@@ -0,0 +1,43 @@
|
|
1
|
+
---
|
2
|
+
- !ruby/struct:VCR::RecordedResponse
|
3
|
+
method: :get
|
4
|
+
uri: http://example.com:80/
|
5
|
+
response: !ruby/object:Net::HTTPOK
|
6
|
+
body: |
|
7
|
+
<HTML>
|
8
|
+
<HEAD>
|
9
|
+
<TITLE>Example Web Page</TITLE>
|
10
|
+
</HEAD>
|
11
|
+
<body>
|
12
|
+
<p>
|
13
|
+
This is not the real response from example.com
|
14
|
+
</p>
|
15
|
+
</BODY>
|
16
|
+
</HTML>
|
17
|
+
|
18
|
+
|
19
|
+
body_exist: true
|
20
|
+
code: "200"
|
21
|
+
header:
|
22
|
+
etag:
|
23
|
+
- "\"24ec5-1b6-4059a80bfd280\""
|
24
|
+
last-modified:
|
25
|
+
- Tue, 15 Nov 2005 13:24:10 GMT
|
26
|
+
connection:
|
27
|
+
- Keep-Alive
|
28
|
+
content-type:
|
29
|
+
- text/html; charset=UTF-8
|
30
|
+
date:
|
31
|
+
- Thu, 25 Feb 2010 15:22:32 GMT
|
32
|
+
server:
|
33
|
+
- Apache/2.2.3 (CentOS)
|
34
|
+
content-length:
|
35
|
+
- "438"
|
36
|
+
age:
|
37
|
+
- "2643"
|
38
|
+
accept-ranges:
|
39
|
+
- bytes
|
40
|
+
http_version: "1.1"
|
41
|
+
message: OK
|
42
|
+
read: true
|
43
|
+
socket:
|
@@ -0,0 +1,45 @@
|
|
1
|
+
---
|
2
|
+
- !ruby/struct:VCR::RecordedResponse
|
3
|
+
method: :get
|
4
|
+
uri: http://example.com:80/before_nested
|
5
|
+
response: !ruby/object:Net::HTTPNotFound
|
6
|
+
body: The before_nested response
|
7
|
+
body_exist: true
|
8
|
+
code: "404"
|
9
|
+
header:
|
10
|
+
content-type:
|
11
|
+
- text/html; charset=iso-8859-1
|
12
|
+
connection:
|
13
|
+
- close
|
14
|
+
server:
|
15
|
+
- Apache/2.2.3 (CentOS)
|
16
|
+
date:
|
17
|
+
- Thu, 25 Feb 2010 15:23:39 GMT
|
18
|
+
content-length:
|
19
|
+
- "287"
|
20
|
+
http_version: "1.1"
|
21
|
+
message: Not Found
|
22
|
+
read: true
|
23
|
+
socket:
|
24
|
+
- !ruby/struct:VCR::RecordedResponse
|
25
|
+
method: :get
|
26
|
+
uri: http://example.com:80/after_nested
|
27
|
+
response: !ruby/object:Net::HTTPNotFound
|
28
|
+
body: The after_nested response
|
29
|
+
body_exist: true
|
30
|
+
code: "404"
|
31
|
+
header:
|
32
|
+
content-type:
|
33
|
+
- text/html; charset=iso-8859-1
|
34
|
+
connection:
|
35
|
+
- close
|
36
|
+
server:
|
37
|
+
- Apache/2.2.3 (CentOS)
|
38
|
+
date:
|
39
|
+
- Thu, 25 Feb 2010 15:23:39 GMT
|
40
|
+
content-length:
|
41
|
+
- "286"
|
42
|
+
http_version: "1.1"
|
43
|
+
message: Not Found
|
44
|
+
read: true
|
45
|
+
socket:
|
@@ -0,0 +1,23 @@
|
|
1
|
+
---
|
2
|
+
- !ruby/struct:VCR::RecordedResponse
|
3
|
+
method: :get
|
4
|
+
uri: http://example.com:80/nested
|
5
|
+
response: !ruby/object:Net::HTTPNotFound
|
6
|
+
body: The nested response
|
7
|
+
body_exist: true
|
8
|
+
code: "404"
|
9
|
+
header:
|
10
|
+
content-type:
|
11
|
+
- text/html; charset=iso-8859-1
|
12
|
+
connection:
|
13
|
+
- close
|
14
|
+
server:
|
15
|
+
- Apache/2.2.3 (CentOS)
|
16
|
+
date:
|
17
|
+
- Thu, 25 Feb 2010 15:19:40 GMT
|
18
|
+
content-length:
|
19
|
+
- "280"
|
20
|
+
http_version: "1.1"
|
21
|
+
message: Not Found
|
22
|
+
read: true
|
23
|
+
socket:
|
@@ -0,0 +1,43 @@
|
|
1
|
+
---
|
2
|
+
- !ruby/struct:VCR::RecordedResponse
|
3
|
+
method: :get
|
4
|
+
uri: http://example.com:80/
|
5
|
+
response: !ruby/object:Net::HTTPOK
|
6
|
+
body: |
|
7
|
+
<HTML>
|
8
|
+
<HEAD>
|
9
|
+
<TITLE>Example Web Page</TITLE>
|
10
|
+
</HEAD>
|
11
|
+
<body>
|
12
|
+
<p>
|
13
|
+
This is not the real response from example.com
|
14
|
+
</p>
|
15
|
+
</BODY>
|
16
|
+
</HTML>
|
17
|
+
|
18
|
+
|
19
|
+
body_exist: true
|
20
|
+
code: "200"
|
21
|
+
header:
|
22
|
+
etag:
|
23
|
+
- "\"24ec5-1b6-4059a80bfd280\""
|
24
|
+
last-modified:
|
25
|
+
- Tue, 15 Nov 2005 13:24:10 GMT
|
26
|
+
connection:
|
27
|
+
- Keep-Alive
|
28
|
+
content-type:
|
29
|
+
- text/html; charset=UTF-8
|
30
|
+
date:
|
31
|
+
- Thu, 25 Feb 2010 15:20:47 GMT
|
32
|
+
server:
|
33
|
+
- Apache/2.2.3 (CentOS)
|
34
|
+
content-length:
|
35
|
+
- "438"
|
36
|
+
age:
|
37
|
+
- "2546"
|
38
|
+
accept-ranges:
|
39
|
+
- bytes
|
40
|
+
http_version: "1.1"
|
41
|
+
message: OK
|
42
|
+
read: true
|
43
|
+
socket:
|
@@ -0,0 +1,43 @@
|
|
1
|
+
---
|
2
|
+
- !ruby/struct:VCR::RecordedResponse
|
3
|
+
method: :get
|
4
|
+
uri: http://example.com:80/
|
5
|
+
response: !ruby/object:Net::HTTPOK
|
6
|
+
body: |
|
7
|
+
<HTML>
|
8
|
+
<HEAD>
|
9
|
+
<TITLE>Example Web Page</TITLE>
|
10
|
+
</HEAD>
|
11
|
+
<body>
|
12
|
+
<p>
|
13
|
+
This is not the real response from example.com
|
14
|
+
</p>
|
15
|
+
</BODY>
|
16
|
+
</HTML>
|
17
|
+
|
18
|
+
|
19
|
+
body_exist: true
|
20
|
+
code: "200"
|
21
|
+
header:
|
22
|
+
etag:
|
23
|
+
- "\"24ec5-1b6-4059a80bfd280\""
|
24
|
+
last-modified:
|
25
|
+
- Tue, 15 Nov 2005 13:24:10 GMT
|
26
|
+
connection:
|
27
|
+
- Keep-Alive
|
28
|
+
content-type:
|
29
|
+
- text/html; charset=UTF-8
|
30
|
+
date:
|
31
|
+
- Thu, 25 Feb 2010 15:22:32 GMT
|
32
|
+
server:
|
33
|
+
- Apache/2.2.3 (CentOS)
|
34
|
+
content-length:
|
35
|
+
- "438"
|
36
|
+
age:
|
37
|
+
- "2643"
|
38
|
+
accept-ranges:
|
39
|
+
- bytes
|
40
|
+
http_version: "1.1"
|
41
|
+
message: OK
|
42
|
+
read: true
|
43
|
+
socket:
|