         # File lib/em/protocols/httpclient.rb, line 94
     94:       def send_request args
     95:         args[:verb] ||= args[:method] # Support :method as an alternative to :verb.
     96:         args[:verb] ||= :get # IS THIS A GOOD IDEA, to default to GET if nothing was specified?
     97:
     98:         verb = args[:verb].to_s.upcase
     99:         unless ["GET", "POST", "PUT", "DELETE", "HEAD"].include?(verb)
    100:           set_deferred_status :failed, {:status => 0} # TODO, not signalling the error type
    101:           return # NOTE THE EARLY RETURN, we're not sending any data.
    102:         end
    103:
    104:         request = args[:request] || "/"
    105:         unless request[0,1] == "/"
    106:           request = "/" + request
    107:         end
    108:
    109:         qs = args[:query_string] || ""
    110:         if qs.length > 0 and qs[0,1] != '?'
    111:           qs = "?" + qs
    112:         end
    113:
    114:         version = args[:version] || "1.1"
    115:
    116:         # Allow an override for the host header if it's not the connect-string.
    117:         host = args[:host_header] || args[:host] || "_"
    118:         # For now, ALWAYS tuck in the port string, although we may want to omit it if it's the default.
    119:         port = args[:port]
    120:
    121:         # POST items.
    122:         postcontenttype = args[:contenttype] || "application/octet-stream"
    123:         postcontent = args[:content] || ""
    124:         raise "oversized content in HTTP POST" if postcontent.length > MaxPostContentLength
    125:
    126:         # ESSENTIAL for the request's line-endings to be CRLF, not LF. Some servers misbehave otherwise.
    127:         # TODO: We ASSUME the caller wants to send a 1.1 request. May not be a good assumption.
    128:         req = [
    129:           "#{verb} #{request}#{qs} HTTP/#{version}",
    130:           "Host: #{host}:#{port}",
    131:           "User-agent: Ruby EventMachine",
    132:         ]
    133:
    134:           if verb == "POST" || verb == "PUT"
    135:             req << "Content-type: #{postcontenttype}"
    136:             req << "Content-length: #{postcontent.length}"
    137:           end
    138:
    139:           # TODO, this cookie handler assumes it's getting a single, semicolon-delimited string.
    140:           # Eventually we will want to deal intelligently with arrays and hashes.
    141:           if args[:cookie]
    142:             req << "Cookie: #{args[:cookie]}"
    143:           end
    144:
    145:           # Basic-auth stanza contributed by Matt Murphy.
    146:           if args[:basic_auth]
    147:             basic_auth_string = ["#{args[:basic_auth][:username]}:#{args[:basic_auth][:password]}"].pack('m').strip.gsub(/\n/,'')
    148:             req << "Authorization: Basic #{basic_auth_string}"
    149:           end
    150:
    151:           req << ""
    152:           reqstring = req.map {|l| "#{l}\r\n"}.join
    153:           send_data reqstring
    154:
    155:           if verb == "POST" || verb == "PUT"
    156:             send_data postcontent
    157:           end
    158:       end