Skip to content
Snippets Groups Projects
Select Git revision
  • c3b1e7363bffd898c84997e0ec32b15f8be45a96
  • master default protected
  • hpke
  • ppc-chacha-4core
  • delete-internal-name-mangling
  • master-updates
  • ppc-gcm
  • ppc-chacha-2core
  • refactor-ecc-mod
  • ppc-chacha-core
  • use-mpn_cnd-functions
  • optimize-ecc-invert
  • default-m4-quote-char
  • power-asm-wip
  • test-fat
  • chacha-3core-neon
  • x86_64-salsa20-2core
  • salsa20-2core-neon
  • bcrypt
  • arm-salsa20-chacha-vsra
  • test-shlib-dir
  • nettle_3.6_release_20200429
  • nettle_3.6rc3
  • nettle_3.6rc2
  • nettle_3.6rc1
  • nettle_3.5.1_release_20190627
  • nettle_3.5_release_20190626
  • nettle_3.5rc1
  • nettle_3.4.1_release_20181204
  • nettle_3.4.1rc1
  • nettle_3.4_release_20171119
  • nettle_3.4rc2
  • nettle_3.4rc1
  • nettle_3.3_release_20161001
  • nettle_3.2_release_20160128
  • nettle_3.1.1_release_20150424
  • nettle_3.1_release_20150407
  • nettle_3.1rc3
  • nettle_3.1rc2
  • nettle_3.1rc1
  • nettle_3.0_release_20140607
41 results

rsa.c

Blame
  • Forked from Nettle / nettle
    Source project has a limited visibility.
    example3 9.59 KiB
    3. This example is a very simple www-server.
    
      For you who are not familiar with WWW (World Wide Web), it works by using
      client program which will fetch files from remote servers when asked.
      Usually by clicking a pitcure or text. This example is a program for the
      server which will send files to any computer that requests them. The
      protocol used to send the file is called HTTP. (HyperText Transfer Protocol)
    
      Usually WWW involves HTML. HTML (HyperText Markup Language) is a way to
      write documents with embedded pictures and links to other pages. These
      links are normally displayed underlined and if you click them your WWW-
      browser will load whatever document that link leads to.
    
    	#!/usr/local/bin/pike
    	
    	/* A very small httpd capable of fetching files only.
    	 * Written by Fredrik Hübinette as a demonstration of Pike.
    	 */
    
      A comment, /* begins the comment, and */ ends it.
    	
    	inherit "/precompiled/port";
    
      Inherit copies all the functionality of /precompiled/port into this program.
      /precompiled/port makes it possible to bind a TCP (Transmission Control
      Protocol, the internet stanard for computer communication) socket to accept
      incoming connections. A socket is simply a number to separate communications
      to and from different programs on the same computer.
    
      Next are some constants that will affect how uHTTPD will operate. This uses
      the preprocessor directive #define. The preprocessor is the first stage in
      the compiling process and can make textual processing of the code before
      it is compiled. As an example, after the first define below, all occurances
      of 'BLOCK' will be replaced with 16060.
    	
    	/* Amount of data moved in one operation */
    	#define BLOCK 16060
    	
    	/* Where do we have the html files ? */
    	#define BASE "/home/hubbe/pike/src/"
    	
    	/* File to return when we can't find the file requested */
    	#define NOFILE "/home/hubbe/www/html/nofile.html"
    	
    	/* Port to open */
    	#define PORT 1905
    
      A port is a destination for a TCP connection. It is simply a number on the
      local computer. 1905 is not the standard port for HTTP connections though,
      which means that if you want to access this WWW server from a browser you
      need to specify the port like this: http://my.host.my.domain:1905/
    
      Next we declare a global variable of the type program called output_class,
      and then we use the class construct to assign a program to it. class {}
      defines a clonable program. (or class for you C++ freaks)
    
    	program output_class=class
    	{
    	  inherit "/precompiled/file" : socket;
    	  inherit "/precompiled/file" : file;
    
      Our new class inherits /precompile/file twice. To be able to separate them
      they are then named 'socket' and 'file'.
    
    	  int offset=0;
    
      Then there is a global variable called offset which is initalized to zero.
      (each instance of this class will have it's own instance of this variable,
       so it is not truly global, but..) 
      Note that the initalization is done when the class is cloned. (or
      instanciated if you prefer C++ terminology)
    
    
      Next we define the function write_callback(). Later the program will go
      into a 'waiting' state, until something is received to process, or until
      there is buffer space available to write output to. When that happens a
      callback will be called to do this. The write_callback() is called when
      there is buffer space available. In the following lines 'void' means that
      it does not return a value. Write callback will be used further down as a
      callback and will be called whenever there is room in the socket output
      buffer.
    	
    	  void write_callback()
    	  {
    	    int written;
    	    string data;
    
      The following line means: call seek in the inherited program 'file'.
    	
    	    file::seek(offset);
    
      Move the file pointer to the where we want to the position we want to read
      from. The file pointer is simply a location in the file, usually it is where
      the last read() ended and the next will begin. seek() can move this pointer
      to where we want it though.
    
    	    data=file::read(BLOCK);
    
      Read BLOCK (16060) bytes from the file. If there are less that that left to
      read only that many bytes will be returned.
    
    	    if(strlen(data))
    	    {
    
       If we managed to read someting...
    
    	      written=socket::write(data);
    
       ... we try to write it to the socket.
    
    	      if(written >= 0)
    	      {
    		offset+=written;
    		return;
    	      }
    
       Update offset if we managed to write to the socket without errors.
    
    	      werror("Error: "+socket::errno()+".\n");
    	    }
    
       If something went wront during writing, or there was nothing left to read
       we destruct this instance of this class.
    
    	    destruct(this_object());
    	  }
    
       That was the end of write_callback()
    
    
       Next we need a variable to buffer the input received in. We initialize it
       to an empty string.
    	
    	  string input="";
    
       And then we define the function that will be called when there is something
       in the socket input buffer. The first argument 'id' is declared as mixed,
       which means that it can contain any type of value. The second argument is
       the contents of the input buffer.
    
    	  void read_callback(mixed id,string data)
    	  {
    	    string cmd;
    	
    	    input+=data;
    
      Append data to the string input. Then we check if we have received a
      a complete line yet. If so we parse this and start ouputting the file.
    
    	    if(sscanf(input,"%s %s%*[\012\015 \t]",cmd,input))
    	    {
    
      This sscanf is pretty complicated, but in essense it means: put the
      first word in 'input' in 'cmd' and the second in 'input' and return 2
      if successfull, 0 otherwise.
    
    	      if(cmd!="GET")
    	      {
    		werror("Only method GET is supported.\n");
    		destruct(this_object());
    		return;
    	      }
    
      If the first word isn't GET print an error message and terminate
      this instance of the program. (and thus the connection)
    	
    	      sscanf(input,"%*[/]%s",input);
    
      Remove the leading slash.
    
    	      input=combine_path(BASE,input);
    
      Combine the requested file with the base of the HTML tree, this gives
      us a full filename beginning with a slash. The HTML tree is the
      directory on the server in which the HTML files are located. Normally
      all files in this directory can be accessed by anybody by using a WWW
      browser. So if a user requests 'index.html' then that file name is first
      added to BASE (/home/hubbe/www/html/ in this case) and if that file exists
      it will be returned to the browser.
    	      
    	      if(!file::open(input,"r"))
    	      {
    
      Try opening the file in read-only mode. If this fails, try opening NOFILE
      instead. Opening the file will enable us to read it later.
    
    		if(!file::open(NOFILE,"r"))
    		{
    
      If this fails too. Write an error message and destruct this object.
    
    		  werror("Couldn't find default file.\n");
    		  destruct(this_object());
    		  return;
    		}
    	      }
    
      Ok, now we set up the socket so we can write the data back.
    	
    	      socket::set_buffer(65536,"w");
    
      Set the buffer size to 64 kilobytes.
    
    	      socket::set_nonblocking(0,write_callback,0);
    
      Make it so that write_callback is called when it is time to write more
      data to the socket.
    
    	      write_callback();
    
      Jump-start the writing.
    	    }
    	  }
    
      That was the end of read_callback().
    
    
      This function is called if the connection is closed while we are reading
      from the socket.
    	  void selfdestruct() { destruct(this_object()); }
    
    
      This function is called when the program is instanciated. It is used
      to set up data the way we want it. Extra arguments to clone() will be
      sent to this function. In this case it is the object representing the
      new connection.
    
    	  void create(object f)
    	  {
    	    socket::assign(f);
    
      We insert the data from the file f into 'socket'.
    
    	    socket::set_nonblocking(read_callback,0,selfdestruct);
    
      Then we set up the callback functions and sets the file nonblocking.
      Nonblocking mode means that read() and write() will rather return that
      wait for I/O to finish. Then we sit back and wait for read_callback to
      be called.
    
    	  }
    
      End of create()
    
    	};
    
      End of the new class.
    	
    
      Next we define the function called when someone connects.
    
    	void accept_callback()
    	{
    	  object tmp_output;
    
      This creates a local variable of type 'object'. An object variable can
      contain a clone of any program. Pike does not consider clones of different
      programs different types. This also means that function calls to objects
      have to be resolved at run time.
    
    	  tmp_output=accept();
    
      The function accept  clones a /precompiled/file and makes this equal to the
      newly connected socket.
    
    	  if(!tmp_output) return;
    
      If it failed we just return.
    
    	  clone(output_class, tmp_output);
    
      Otherwise we clone an instanec of 'output_class' and let it take care of the
      connection. Each clone of output_class will have it's own set of global
      variables, which will enable many connections to be active at the same
      time without data being mixed up. Note that the programs will not actually
      run simulataneously though.
    
    	  destruct(tmp_output);
    
      Destruct the object returned by accept(), output_class has already copied
      the contents of this object.
    
    	}
    
    
      Then there is main, the function that gets it all started.
      	
    	int main(int argc, string *argv)
    	{
    	  werror("Starting minimal httpd\n");
    
      Write an encouraging message to stderr.
    	
    	  if(!bind(PORT, accept_callback))
    	  {
    	    werror("Failed to open socket (already bound?)\n");
    	    return 17;
    	  }
    
    
      Bind PORT and set it up to call accept_callback as soon as someone connects
      to it. If the bind() fails we write an error message and return the 17 to
      indicate failiure.
    	
    	  return - 17; /* Keep going */
    
      If everything went ok, we return -17, any negative value returned by main()
      means that the program WONT exit, it will hang around waiting for events
      instead. (like someone connecting)
    	}
    
      End of uhttpd.pike