3

私は小さなウェブサーバーを書いています。を読みたいですHTTP Request。体が関与していないときに機能します。しかし、ボディが送信されると、ボディの内容を満足のいく方法で読み取ることができません。

経由でクライアントからのデータを読み取りますTCPSocket。このTCPSocket::getsメソッドは、本体のデータが受信されるまで読み取ります。EOFHTTP リクエスト本文の末尾には、区切り文字や send to signal はありません。HTTP/1.1 仕様 - セクション 4.4には、メッセージの長さを取得する 5 つのケースがリストされています。ポイント1)は機能します。ポイント 2) と 4) は、私のアプリケーションには関係ありません。ポイント 5) は、応答を送信する必要があるため、オプションではありません。

フィールドの値を読み取ることができますContent-Length。しかし、read(contentlength)またはを介してHTTPリクエストの最後の部分を読み取るようにTCPSocketを「説得」しようとするとrcv(contentlength)、成功しません。ヘッダーとボディを分離するまで行ごとに読む\r\nことはできますが、その後は行き詰まります-少なくとも私がやりたい方法で。

だから私の質問は:

コードで意図したようにする可能性はありますか? 正しく読むという私の目標を達成するためのより良い方法はありますかHTTP Request(私が本当に望んでいます)?

これが実行可能なコードです。やりたい部分はコメントに。

#!/usr/bin/ruby
require 'socket'

server = TCPServer.new 2000
loop do
  Thread.start(server.accept) do |client|
    hascontent = false
    contentlength = 0
    content = ""
    request = ""
    #This seems to work, but I'm not really happy with it, too much is happening in
    #the loop
    while(buf = client.readpartial(4096))
       request = request + buf
       split = request.split("\r\n")
       puts request
       puts request.dump
       puts split.length
       puts split.inspect
       if(request.index("\r\n\r\n")>0)
         break
       end
    end
#This part is commented out because it doesn't work
=begin
    while(line = client.gets)
       puts ":" + line
       request = request + line
       if(line.start_with?("Content-Length"))
         hascontent = true
         split = line.split(' ')
         contentlength = split[1]
       end
       if(line == "\r\n" and !hascontent)
         break
       end
       if(line == "\r\n" and hascontent)
         puts "Trying to get content :P"
         puts contentlength
         puts content.length
         puts client.inspect
         #tried read, with and without parameter, rcv, also with and 
         #without param and their nonblocking couterparts
         #where does my thought process go in the wrong direction  
         while(readin = client.readpartial(contentlength))
           puts readin
           content = content + readin
         end
         break
       end
    end
=end
    puts request
    client.close
 end
4

1 に答える 1