hayabusa 0.0.25 → 0.0.30

Sign up to get free protection for your applications and to get access to all the features.
@@ -3,7 +3,7 @@ require "time"
3
3
  #This object writes headers, trailing headers, status headers and more for HTTP-sessions.
4
4
  class Hayabusa::Http_session::Response
5
5
  attr_accessor :chunked, :cgroup, :nl, :status, :http_version, :headers, :headers_trailing, :headers_sent, :socket
6
-
6
+
7
7
  STATUS_CODES = {
8
8
  100 => "Continue",
9
9
  200 => "OK",
@@ -22,16 +22,17 @@ class Hayabusa::Http_session::Response
22
22
  403 => "Forbidden",
23
23
  404 => "Not Found",
24
24
  408 => "Request Timeout",
25
+ 415 => "Unsupported media type",
25
26
  500 => "Internal Server Error"
26
27
  }
27
28
  NL = "\r\n"
28
-
29
+
29
30
  def initialize(args)
30
31
  @chunked = false
31
32
  @socket = args[:socket]
32
33
  @hb = args[:hb]
33
34
  end
34
-
35
+
35
36
  def reset(args)
36
37
  @status = 200
37
38
  @http_version = args[:http_version]
@@ -45,20 +46,20 @@ class Hayabusa::Http_session::Response
45
46
  @headers_trailing = {}
46
47
  @mode = args[:mode]
47
48
  @cookies = []
48
-
49
+
49
50
  @headers = {
50
51
  "date" => ["Date", Time.now.httpdate]
51
52
  }
52
-
53
+
53
54
  if args[:mode] != :cgi and (!args.key?(:chunked) or args[:chunked])
54
55
  @chunked = true
55
56
  end
56
57
  end
57
-
58
+
58
59
  def header(key, val)
59
60
  lines = val.to_s.count("\n") + 1
60
61
  raise "Value contains more lines than 1 (#{lines})." if lines > 1
61
-
62
+
62
63
  if !@headers_sent
63
64
  @headers[key.to_s.downcase.strip] = [key, val]
64
65
  else
@@ -66,32 +67,32 @@ class Hayabusa::Http_session::Response
66
67
  @headers_trailing[key.to_s.downcase.strip] = [key, val]
67
68
  end
68
69
  end
69
-
70
+
70
71
  # Returns the value of a header.
71
72
  def get_header_value(header)
72
73
  header_p = header.to_s.downcase.strip
73
-
74
+
74
75
  gothrough = [@headers, @headers_trailing]
75
76
  gothrough.each do |headers|
76
77
  headers.each do |key, val|
77
78
  return val[1] if header_p == key
78
79
  end
79
80
  end
80
-
81
+
81
82
  return nil
82
83
  end
83
-
84
+
84
85
  # Returns true if the given header-name is sat.
85
86
  def has_header?(header)
86
87
  header_p = header.to_s.downcase.strip
87
88
  return @headers.key?(header_p) || @headers_trailing.key?(header_p)
88
89
  end
89
-
90
+
90
91
  def cookie(cookie)
91
92
  @cookies << cookie
92
93
  @session_cookie[cookie["name"]] = cookie["value"]
93
94
  end
94
-
95
+
95
96
  def header_str
96
97
  if @http_version == "1.1" && @chunked
97
98
  self.header("Connection", "Keep-Alive")
@@ -99,9 +100,9 @@ class Hayabusa::Http_session::Response
99
100
  elsif @http_version == "1.1" && get_header_value("content-length").to_i > 0
100
101
  self.header("Connection", "Keep-Alive")
101
102
  end
102
-
103
+
103
104
  self.header("Keep-Alive", "timeout=15, max=30") if self.get_header_value("connection") == "Keep-Alive"
104
-
105
+
105
106
  if @skip_statuscode
106
107
  res = ""
107
108
  else
@@ -110,67 +111,67 @@ class Hayabusa::Http_session::Response
110
111
  else
111
112
  res = "HTTP/1.1 #{@status}"
112
113
  end
113
-
114
+
114
115
  code = STATUS_CODES[@status]
115
116
  res << " #{code}" if code
116
117
  res << NL
117
118
  end
118
-
119
+
119
120
  # The status header is used to make CGI or FCGI use the correct status-code.
120
121
  self.header("Status", "#{@status} #{STATUS_CODES[@status]}")
121
-
122
+
122
123
  @headers.each do |key, val|
123
124
  res << "#{val[0]}: #{val[1]}#{NL}"
124
125
  end
125
-
126
+
126
127
  if @http_version == "1.1"
127
128
  @trailers.each do |trailer|
128
129
  res << "Trailer: #{trailer}#{NL}"
129
130
  end
130
131
  end
131
-
132
+
132
133
  @cookies.each do |cookie|
133
134
  res << "Set-Cookie: #{Knj::Web.cookie_str(cookie)}#{NL}"
134
135
  end
135
-
136
+
136
137
  res << NL
137
-
138
+
138
139
  return res
139
140
  end
140
-
141
+
141
142
  def write
142
143
  # Write headers to socket.
143
144
  @socket.write(self.header_str)
144
145
  @headers_sent = true
145
146
  @cgroup.chunked = @chunked
146
-
147
+
147
148
  # Set the content-length on the content-group to enable write-lenght-validation.
148
149
  if self.has_header?("content-length")
149
150
  @cgroup.content_length = self.get_header_value("content-length").to_i
150
151
  else
151
152
  @cgroup.content_length = nil
152
153
  end
153
-
154
+
154
155
  if @chunked
155
156
  @cgroup.write_to_socket
156
157
  @socket.write("0#{NL}")
157
-
158
+
158
159
  @headers_trailing.each do |header_id_str, header|
159
160
  @socket.write("#{header[0]}: #{header[1]}#{NL}")
160
161
  end
161
-
162
+
162
163
  @socket.write(NL)
163
164
  else
164
165
  @cgroup.write_to_socket
165
166
  end
166
-
167
+
167
168
  # Validate that no more has been written than given in content-length, since that will corrupt the client.
168
169
  if self.has_header?("content-length")
169
170
  length = cgroup.length_written
170
171
  content_length = self.get_header_value("content-length").to_i
171
172
  raise "More written than given in content-length: #{length}, #{content_length}" if length != content_length
172
173
  end
173
-
174
+
174
175
  # Close socket if that should be done.
175
176
  if @close and @mode != :cgi
176
177
  @hb.log_puts("Hauabusa: Closing socket.")