Personal tools
You are here: Home ブログ uchida Categories Ada
« December 2010 »
Su Mo Tu We Th Fr Sa
      1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31  
Categories
JavaScript
Go
Ada
Delphi
junk
 
Document Actions

Ada

Up one level

Document Actions

Adaで超いい加減HTTPサーバ

Adaのタスクはもっと評価されいい、のかな?

with Ada.Text_IO; use Ada.Text_IO;
with Ada.Strings.Maps; use Ada.Strings.Maps;
with Ada.Strings.Fixed; use Ada.Strings.Fixed;
with Ada.Strings.Unbounded; use Ada.Strings.Unbounded;
with Ada.Streams;
with Ada.Streams.Stream_IO;
with GNAT.Sockets;

with Ada.Integer_Text_IO;
use Ada.Integer_Text_IO;

procedure Run_Server is
package GS renames GNAT.Sockets;

CRLF: constant String := ASCII.CR & ASCII.LF;
task type HTTP_Request is
entry Process(Client_Socket: in GS.Socket_Type);
end;

task body HTTP_Request is
Client: GS.Socket_Type;
Connection: GS.Stream_Access;

function Read return String is
Request_Error: exception;

Offset: Ada.Streams.Stream_Element_Count;
Buffer: Ada.Streams.Stream_Element_Array(1..1024);
Result: Unbounded_String := To_Unbounded_String("");
begin
loop
GS.Receive_Socket(Client, Buffer, Offset);
if Natural(Offset) = 0 then
Put_Line("EOF");
raise Request_Error;
end if;

for i in 1..Offset loop
Result := Result & Character'Val(Buffer(i));
end loop;
exit when Tail(Result, 4) = CRLF & CRLF;
end loop;
return To_String(Result);
end;

function Parse_URL(Headers: String) return String is
first: Positive;
last: Natural;
begin
Find_Token(Headers, To_Set(" "), Ada.Strings.Outside, first, last);
Find_Token(Headers(last+1..Headers'Last), To_Set(" "), Ada.Strings.Outside, first, last);

declare
Url: String := Headers(first+1..last);
begin
if Url = "" or else Url(Url'Last) = '/' then
Url := Url & "index.html";
end if;
return Url;
end;
end;

procedure Write(Url: String) is
package ASS_IO renames Ada.Streams.Stream_IO;
File: ASS_IO.File_Type;
begin
ASS_IO.Open(File, ASS_IO.In_File, Url);

declare
File_Stream: ASS_IO.Stream_Access;
Offset: Ada.Streams.Stream_Element_Count;
File_Buffer: Ada.Streams.Stream_Element_Array(1..1024);
begin
String'Write(Connection, "HTTP/1.0 200 OK" & CRLF & CRLF);
File_Stream := ASS_IO.Stream(File);

loop
Ada.Streams.Read(File_Stream.all, File_Buffer, Offset);
exit when Natural(Offset) = 0;

Connection.Write(File_Buffer(1..Offset));
end loop;
ASS_IO.Close(File);
exception
when others => ASS_IO.Close(File);
end;
Put_Line("done");
end;
begin
accept Process(Client_Socket: in GS.Socket_Type) do
Client := Client_Socket;
end Process;
Connection := GS.Stream(Client);

declare
Headers: String := Read;
Url: String := Parse_URL(Headers);
begin
Write(Url);
end;

GS.Close_Socket(Client);
exception
when others =>
GS.Close_Socket(Client);
end;

type HTTP_Request_Access is access HTTP_Request;
Server: GS.Socket_Type;
Server_Address: GS.Sock_Addr_Type;
Client: GS.Socket_Type;
Client_Address: GS.Sock_Addr_Type;
begin
GS.Initialize;
GS.Create_Socket(Server);
Server_Address.Addr := GS.Inet_Addr("127.0.0.1");
Server_Address.Port := 1972;
GS.Bind_Socket(Server, Server_Address);
GS.Listen_Socket(Server);

loop
GS.Accept_Socket(Server, Client, Client_Address);
Put_Line("Request came");
declare
req: HTTP_Request_Access := new HTTP_Request;
begin
req.Process(Client);
end;
end loop;
end;

Goのgoroutine、Adaのタスクと来たら次はScalaのアクターで書くとどうなるのか、是非見てみたいですね。

Category(s)
junk
Ada
The URL to Trackback this entry is:
http://dev.ariel-networks.com/Members/uchida/ada8d853044304452a06e1bhttp30b530fc/tbping

Copyright(C) 2001 - 2006 Ariel Networks, Inc. All rights reserved.