[SCM] Lisaac compiler branch, master, updated. lisaac-0.12-622-g522bd91

ontologiae ontologiae at ordinateur-de-ontologiae-3.local
Tue Mar 30 17:28:34 UTC 2010


The following commit has been merged in the master branch:
commit 522bd91f9a3dbccd8dc20d8ca6d8bc607209a484
Author: ontologiae <ontologiae at ordinateur-de-ontologiae-3.local>
Date:   Tue Mar 30 19:28:17 2010 +0200

    Http server update

diff --git a/lib/standard/http/http_server.li b/lib/standard/http/http_server.li
index 346284c..85c4fad 100644
--- a/lib/standard/http/http_server.li
+++ b/lib/standard/http/http_server.li
@@ -19,16 +19,16 @@
 //                     http://isaacproject.u-strasbg.fr/                     //
 ///////////////////////////////////////////////////////////////////////////////
 Section Header
-
+  
   + name      := HTTP_SERVER;
 
   - copyright := "2003-2010 Sonntag Benoit";
 
   - author    := "Sonntag Benoit (sonntag at icps.u-strasbg.fr)";
   - comment   := "The main prototype";
-
+  
   - external  :=
-`
+`  
 #include <sys/types.h>
 #include <string.h>
 #include <unistd.h>
@@ -36,49 +36,64 @@ Section Header
 
 #include <netinet/in.h>
 #include <netdb.h>
-#include <sys/socket.h>
+#include <sys/socket.h>  
 
 struct sockaddr_in address;
 `;
-
+  
 Section Inherit
 
   - parent_object:OBJECT := OBJECT;
-
+  
 Section Private
-
+   
   //
   // Parameters
   //
-
+  
   + h_socket:INTEGER;
-
+  
   - queue_size:INTEGER := 5;
-
+  
   - buffer:STRING := STRING.create 1024;
 
+  - tmp_header : HTTP_HEADER := HTTP_HEADER.create;
+
+  - post_block_list : HASHED_DICTIONARY(STRING,{HASHED_DICTIONARY(STRING,STRING);STRING}) :=  HASHED_DICTIONARY(STRING,{HASHED_DICTIONARY(STRING,STRING);STRING}).create;
+    // HASHED_DICTIONARY(
+    // STRING : post method name ,
+    //{HASHED_DICTIONARY(STRING,STRING);STRING} : Block with post method parameters arguments, and result
+    // )
+    //TODO : gestion des cookies !
+  
   //
   // Error.
   //
-
+  
   - socket_error:INTEGER := -1;
-
+   
   - error msg:ABSTRACT_STRING <-
   (
     msg.print; '\n'.print;
     die_with_code 1;
   );
-
+    
 Section Public
-
+  
   - log:STRING := STRING.create 1024;
+  - debug_flag : BOOLEAN;
 
-  - listen port:INTEGER do act:{} <-
+  - set_debug_flag b : BOOLEAN <-
+  (
+    debug_flag := b;
+  );
+    
+  - listen port:INTEGER action act:{} <-
   ( + h_server_socket,error,tmp:INTEGER;
     + n_address_size:INTEGER;
     + storage:NATIVE_ARRAY(CHARACTER);
-
-    n_address_size := `sizeof(address)`:INTEGER;
+    
+    n_address_size := `sizeof(address)`:INTEGER;    
     h_server_socket := `socket(AF_INET,SOCK_STREAM,0)`:INTEGER;
     (h_server_socket = socket_error).if {
       error "Error : create socket!";
@@ -88,100 +103,112 @@ Section Public
     address.sin_port=htons(@port);
     address.sin_family=AF_INET;
     `;
-
+    
     error := `bind(@h_server_socket,(struct sockaddr*)&address,sizeof(address))`:INTEGER;
     (error = socket_error).if {
       error "Error : Bind()";
     };
-    `getsockname(@h_server_socket, (struct sockaddr *) &address,(socklen_t *)&@n_address_size)`;
-
-    log.append "Opened socket as fd (";
-    h_server_socket.append_in log;
-    log.append ") on port (";
-    `ntohs(address.sin_port)`:INTEGER.append_in log;
-    log.append ") for stream i/o\n";
-
+    `getsockname(@h_server_socket, (struct sockaddr *) &address,(socklen_t *)&@n_address_size)`;  
+    debug_flag.if {
+      log.append "Opened socket as fd (";
+      h_server_socket.append_in log;
+      log.append ") on port (";
+      `ntohs(address.sin_port)`:INTEGER.append_in log;
+      log.append ") for stream i/o\n";
+    };
+    
     /*
     "Server\
     \\nsin_family        = ".print;
     `address.sin_family`:INTEGER.print;
     "\nsin_addr.s_addr   = ".print;
-    `address.sin_addr.s_addr`:INTEGER.print;
+    `address.sin_addr.s_addr`:INTEGER.print; 
     "\nsin_port          = ".print;
     `ntohs(address.sin_port)`:INTEGER.print;
-    '\n'.print;
+    '\n'.print;    
     "\nMaking a listen queue of ".print;
     queue_size.print;
     " elements".print;
     */
-
-    // establish listen queue
+        
+    // establish listen queue 
     tmp := queue_size;
     (`listen(@h_server_socket, at tmp)`:INTEGER = socket_error).if {
       error "Could not listen";
     };
     {
-      log.append "Waiting for a connection\n";
-      // get the connected socket
+      debug_flag.if {
+       log.append "Waiting for a connection\n";
+      };
+      // get the connected socket 
       h_socket := `accept(@h_server_socket,(struct sockaddr*)&address,(socklen_t *)&@n_address_size)`:INTEGER;
-      log.append "Got a connection\n";
-      act.value;
+      debug_flag.if { 
+        log.append "Got a connection\n";
+      }; 
+
+      // We have a connection, so act is valued
+      act.value;            
     }.endless_loop;
   );
-
+  
   - send buf:ABSTRACT_STRING <-
   ( + storage:NATIVE_ARRAY(CHARACTER);
     + loc_h_socket,count:INTEGER;
-
-    log.append "send buffer\n";
+    debug_flag.if {
+     log.append "send buffer\n";
+    }; 
     storage := buf.to_external;
     count   := buf.count + 1;
     loc_h_socket := h_socket;
     `write(@loc_h_socket, at storage, at count)`;
   );
-
+  
   - receive buf:STRING <-
   // BSBS: Plutot  faire un append que un copy
   ( + loc_h_socket,capacity:INTEGER;
     + storage:NATIVE_ARRAY(CHARACTER);
-
-    log.append "receive buffer\n";
+    
+    debug_flag.if {
+     log.append "receive buffer\n";
+    };
     storage  := buf.to_external;
     capacity := buf.capacity;
     loc_h_socket := h_socket;
     `read(@loc_h_socket, at storage, at capacity)`;
     buf.from_external storage;
-  );
-
+  );      
+  
   - close <-
-  // close socket
+  // close socket 
   ( + loc_h_socket:INTEGER;
-    log.append "Closing the socket\n";
+    debug_flag.if {
+     log.append "Closing the socket\n";
+    };
     loc_h_socket := h_socket;
     (`close(@loc_h_socket)`:INTEGER = socket_error).if {
       error "Could not close socket";
-    };
-  );
-
+    };    
+  );  
+  
   - convert buf:STRING to_dictionary dico:HASHED_DICTIONARY(STRING,STRING) <-
   ( + idx_start,idx_end,idx:INTEGER;
     + key,value:STRING;
     + sep:CHARACTER;
-
+    
     sep := ' ';
     idx_start := buf.lower;
     {
-      idx_end := buf.index_of '\n' since idx_start;
+      idx_end := buf.index_of '\n' since idx_start;      
       idx := buf.index_of sep since idx_start;
       (idx < idx_end).if {
-        sep := ':';
+        sep := ':';        
         key   := buf.substring idx_start to (idx-1);
-        {buf.item (idx + 1) = ' '}.while_do {
-          idx := idx + 1;
-        };
-        {buf.item (idx_end - 1) <= ' '}.while_do {
-          idx_end := idx_end - 1;
+        {buf.item (idx + 1) = ' '}.while_do { 
+          idx := idx + 1; 
         };
+        {buf.item (idx_end - 1) <= ' '}.while_do { 
+          idx_end := idx_end - 1; 
+        };        
         value := buf.substring (idx+1) to (idx_end-1);
         dico.put value to key;
       };
@@ -189,13 +216,65 @@ Section Public
     }.do_while {idx_end <= buf.count};
   );
 
+   - convert buf : STRING to_http_header header : HTTP_HEADER <-
+  ( + idx_start,idx_end,idx:INTEGER;
+    + key,value:STRING;
+    + sep:CHARACTER;
+    
+    sep := ' ';
+    idx_start := buf.lower;
+    {
+      idx_end := buf.index_of '\n' since idx_start;      
+      idx := buf.index_of sep since idx_start;
+      (idx < idx_end).if {
+        sep := ':';        
+        key   := buf.substring idx_start to (idx-1);
+        {buf.item (idx + 1) = ' '}.while_do { 
+          idx := idx + 1; 
+        };
+        {buf.item (idx_end - 1) <= ' '}.while_do { 
+          idx_end := idx_end - 1; 
+        };        
+        value := buf.substring (idx+1) to (idx_end-1);
+        //dico.put value to key;
+
+        //TODO : Virer le http/1.1 à la fin de l'uri !
+
+        key.when "GET" then             { header.set_verb "GET"; header.set_uri value;} 
+           .when "POST" then            { header.set_verb "POST"; header.set_uri value;}
+           .when "PUT" then             { header.set_verb "PUT";  header.set_uri value;}
+           .when "DELETE" then          { header.set_verb "DELETE"; header.set_uri value;}
+           .when "Host" then            { header.set_host value;}
+           .when "User-Agent" then      { header.set_user_agent value;}
+           .when "Accept" then          { header.set_accept_mime value;}
+           .when "Accept-Encoding" then { header.set_accept_encoding value;} 
+           .when "Accept-Charset" then  { header.set_accept_charset value;} 
+           .when "Keep-Alive" then      { header.set_keep_alive value;} 
+           .when "Connection" then      { header.set_connection value;}
+           .when "Cookie"     then      { header.set_cookie value;}
+           .case_else                   { //("Unknown key :"+key).println;
+             };
+        
+         debug_flag.if {
+          //"clé".count.println;
+          //key.count.println;
+          //("clé"+key).count.println;
+          //("Key="+key + " Value=".to_string+value).println; 
+        };
+      };
+      idx_start := idx_end + 1;
+    }.do_while {idx_end <= buf.count};
+  );
+  
+
+
   //
   // High level.
   //
-
+  
   - send buf:ABSTRACT_STRING type_mime type:ABSTRACT_STRING <-
   (
-    buffer.copy
+    buffer.copy 
     "HTTP/1.1 200 OK\n\
     \Date: ";
     SYSTEM.get_current_date.append_in buffer;
@@ -206,7 +285,7 @@ Section Public
     \Content-Length: ";
     buf.count.append_in buffer;
     buffer.append "\n\
-    \Connection: close\n\
+    \Connection: close\n\        
     \Content-type: ";
     buffer.append type;
     buffer.append "\n\n";
@@ -215,3 +294,114 @@ Section Public
     buffer.append "\n\n";
     send buffer;
   );
+
+
+  //
+  // Receiver manager
+  //
+
+  - receive_get_do blc : {HTTP_HEADER;} <-
+    ( + my_buf : STRING;
+      my_buf := STRING.create 512;
+      receive my_buf;
+      convert my_buf to_http_header tmp_header;
+      (tmp_header.verb ~= "GET").if {blc.value tmp_header;};
+    );
+
+  - receive_do_get get : {HTTP_HEADER;} post post : {HTTP_HEADER;} put put :  {HTTP_HEADER;} delete del :  {HTTP_HEADER;} <-
+    ( + my_buf : STRING;
+      my_buf := STRING.create 512;
+      receive my_buf;
+      convert my_buf to_http_header tmp_header;
+      tmp_header.verb.when "GET"    then {get.value tmp_header;}
+                     .when "POST"   then {post.value tmp_header;}
+                     .when "PUT"    then {put.value tmp_header;}
+                     .when "DELETE" then {del.value tmp_header;};
+    );
+
+
+
+
+     - receive_do_get get : {HTTP_HEADER;} post post : {HTTP_HEADER;} <-
+    ( + my_buf : STRING;
+      my_buf := STRING.create 512;
+      receive my_buf;
+      convert my_buf to_http_header tmp_header;
+      tmp_header.verb.when "GET"    then {get.value tmp_header;}
+                     .when "POST"   then {post.value tmp_header;};
+    );
+
+
+    //
+    // Tools
+    //
+
+
+
+    - get_file uri : ABSTRACT_STRING : STRING <-
+    ( + filename : ABSTRACT_STRING;
+      filename := uri.substring 2 to (uri.count -1);
+      FS_MIN.open_as_string filename
+    );
+
+    // Pour le post : on reçoit une hash de clé/valeur ainsi qu'un nom de post : on regarde si on a un {HASH(STR,STR);STR} dans le HASH(STR, {HASH(STR,STR);STR}) et on l'exécute
+
+
+    - decode_parameters param : STRING : HASHED_DICTIONARY(STRING,STRING) <-
+    ( + res : HASHED_DICTIONARY(STRING,STRING);
+      + params : ARRAY(STRING);
+      res :=  HASHED_DICTIONARY(STRING,STRING).create;
+      // On cherche le premier ?
+      // Ensuite on split avec le &
+      // Chaque morceaux est splité avec le =
+
+      // Algo pas très perf...
+      params := (param.substring  (param.substring_index ("?",1)) to (param.count - 1)).split_str "&";
+      params.foreach { e : STRING;
+        res.put (e.substring  (e.substring_index ("=",0) - 1) to (e.count-1)) to (e.substring 0 to (e.substring_index ("=",0) - 1)); 
+      };
+      res
+    );
+
+
+    //
+    // POST manager
+    //
+
+    
+    // Un pattern d'optim : à l'usage, le serveur recevra des requetes post et ira switcher sur le block correspondant.
+    // Au lieu d'utiliser l'infra de HASHED_DICTIONARY , peut être qu'il y aurait moyen de fire un bête switch sur le nom ?
+    - add_post name : ABSTRACT_STRING action blc : {HASHED_DICTIONARY(STRING,STRING); STRING} <-
+    ( 
+      post_block_list.put blc to name;
+    );
+
+
+
+
+    //
+    // Web Server
+    //
+
+
+    - start_server_on_port port : INTEGER <-
+    (
+      listen port action {
+        receive_get_do { h : HTTP_HEADER;
+          //TODO : Virer ce hack !!
+          s := h.uri;
+          s.replace_all "HTTP/1.1" with "";
+          ("Request with URI : " +s).printline;
+          my_buf :=  get_file s;
+          send my_buf type_mime "text/html";
+        } post { h : HTTP_HEADER;
+           //TODO : Virer ce hack !!
+          s := h.uri;
+          s.replace_all "HTTP/1.1" with "";
+          ("POST with URI : " +s).printline
+          // Decoupage des paramètres
+
+        };
+        close;
+      };
+    );

-- 
Lisaac compiler



More information about the Lisaac-commits mailing list