mirror of https://gitee.com/bigwinds/arangodb
163 lines
4.1 KiB
Ruby
163 lines
4.1 KiB
Ruby
# coding: utf-8
|
|
|
|
class ArangoMultipartBody
|
|
|
|
@boundary = ""
|
|
|
|
@parts = [ ]
|
|
|
|
################################################################################
|
|
## initialize a multipart message body
|
|
################################################################################
|
|
|
|
def initialize (boundary = nil)
|
|
@parts = [ ]
|
|
if boundary.nil?
|
|
@boundary = "XXXArangoBatchXXX"
|
|
else
|
|
@boundary = boundary
|
|
end
|
|
end
|
|
|
|
################################################################################
|
|
## get the message boundary
|
|
################################################################################
|
|
|
|
def getBoundary
|
|
return @boundary
|
|
end
|
|
|
|
################################################################################
|
|
## add a part to a multipart message body
|
|
################################################################################
|
|
|
|
def addPart (method, url, headers, body, contentId = "")
|
|
part = { :method => method, :url => url, :headers => headers, :body => body, :contentId => contentId }
|
|
@parts.push(part)
|
|
end
|
|
|
|
################################################################################
|
|
## split the response body into its individual parts
|
|
################################################################################
|
|
|
|
def getParts (boundary, body)
|
|
parts = [ ]
|
|
valid = false
|
|
|
|
while 1
|
|
position = body.index("--" + boundary)
|
|
|
|
break if position != 0 or position == nil
|
|
|
|
follow = body.slice(position + boundary.length + 2, 2)
|
|
|
|
break if follow != "\r\n" and follow != "--"
|
|
|
|
if follow == "--"
|
|
valid = true
|
|
break
|
|
end if
|
|
|
|
# strip boundary start from body
|
|
body = body.slice(position + boundary.length + 4, body.length)
|
|
|
|
# look for boundary end
|
|
final = body.index("--" + boundary)
|
|
|
|
break if final == nil
|
|
|
|
# extract the part
|
|
partTotal = body.slice(0, final)
|
|
|
|
# look for envelope bounds
|
|
position = partTotal.index("\r\n\r\n");
|
|
break if position == nil
|
|
|
|
|
|
r = Regexp.new('content-id: ([^\s]+)', Regexp::IGNORECASE)
|
|
|
|
if r.match(partTotal.slice(0, position))
|
|
contentId = Regexp.last_match(1)
|
|
else
|
|
contentId = ""
|
|
end
|
|
|
|
|
|
# strip envelope
|
|
partTotal = partTotal.slice(position + 4, partTotal.length)
|
|
|
|
# look for actual header & body
|
|
partHeader, partBody = "", ""
|
|
position = partTotal.index("\r\n\r\n");
|
|
|
|
break if position == nil
|
|
|
|
partHeader = partTotal.slice(0, position)
|
|
partBody = partTotal.slice(position + 4, partTotal.length)
|
|
|
|
partHeaders = { }
|
|
status = 500
|
|
lineNumber = 0
|
|
|
|
# parse headers and status code
|
|
|
|
partHeader.each_line("\r\n") do |line|
|
|
if lineNumber == 0
|
|
position = line.index("HTTP/1.1 ")
|
|
break if position == nil
|
|
status = line.slice(9, 3).to_i
|
|
else
|
|
key, void, value = line.partition(":")
|
|
partHeaders[key.strip] = value.strip
|
|
end
|
|
lineNumber = lineNumber + 1
|
|
end
|
|
|
|
part = { :headers => partHeaders, :body => partBody, :status => status, :contentId => contentId }
|
|
parts.push(part)
|
|
|
|
body = body.slice(final, body.length)
|
|
end
|
|
|
|
if not valid
|
|
raise "invalid multipart response received"
|
|
end
|
|
|
|
parts
|
|
end
|
|
|
|
################################################################################
|
|
## get the string representation of a multipart message body
|
|
################################################################################
|
|
|
|
def to_s
|
|
body = ""
|
|
@parts.each do|part|
|
|
# boundary
|
|
body += "--" + @boundary + "\r\n"
|
|
# header
|
|
body += "Content-Type: application/x-arango-batchpart"
|
|
|
|
if part[:contentId] != ""
|
|
body += "\r\nContent-Id: " + part[:contentId]
|
|
end
|
|
|
|
body += "\r\n\r\n"
|
|
|
|
# inner header
|
|
body += part[:method] + " " + part[:url] + " HTTP/1.1\r\n"
|
|
|
|
part[:headers].each do|key, value|
|
|
body += key + ": " + value + "\r\n"
|
|
end
|
|
# header/body separator
|
|
body += "\r\n"
|
|
|
|
# body
|
|
body += part[:body] + "\r\n"
|
|
end
|
|
body += "--" + @boundary + "--\r\n"
|
|
end
|
|
|
|
end
|