Example #1
0
int main(int argc, char *argv[])
{
   char header[] = "Powered-by: ANSI C scripts\r\n";
   http_header(HEAD_ADD, header, sizeof(header) - 1, argv);
   
   xbuf_cat(get_reply(argv), "Look at the HTTP headers");

   return 200; // return an HTTP code (200:'OK')
}
Example #2
0
	void flush(void)
	{
		// TODO: flush() can later return some info about the flushed data, e.g. size
		if (!this->headersSet)
		{
		    this->flushHeaders();
		}
		xbuf_cat(this->httpOut, (char *) this->payload.c_str());
		u32toa(this->httpOut->ptr + this->ptrHeaderSize, this->httpOut->len - this->headersSize);		
	}
Example #3
0
int main(int argc, char *argv[])
{
  xbuf_t data;
  xbuf_init(&data);
  xbuf_cat(&data,
    "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Morbi sit amet "
    "quam purus, vitae fermentum turpis. Nam in augue mi. Donec suscipit moles"
    "tie felis, eget rhoncus risus pharetra in. Sed id diam id felis fringilla"
    " adipiscing non vitae odio. Etiam vulputate tristique elit, nec eleifend"
    " mauris scelerisque eu. Vestibulum luctus, enim a luctus posuere, mauris"
    " mauris rutrum mi, eget fermentum massa tortor id enim. Nulla feugiat "
    "porta urna quis laoreet. Morbi metus ante, commodo quis dictum vitae, "
    "rhoncus a libero. Cras viverra feugiat orci id interdum. Duis pulvinar "
    "neque id erat adipiscing facilisis. Maecenas vitae urna risus, euismod"
    " sollicitudin risus."
  );
  
  char gzipped[4096];
  
  u32 len = zlib_cmp(data.ptr, 0, data.len, gzipped, sizeof(gzipped), 1);
  
  printf("Original length: %i\n", data.len);
  printf("Gzipped length:  %i\n\n", len);
  
  xbuf_t *reply = get_reply(argv);
  
  xbuf_xcat(reply,
    "HTTP/1.1 200 OK\r\n"
    "Content-Type: text/plain\r\n"
    "Content-Length: %i\r\n"
    "Content-Encoding: gzip\r\n\r\n",
    len
  );
  
  xbuf_ncat(reply, gzipped, len);
  
  xbuf_free(&data);

  return -1; //custom headers
}
Example #4
0
int main(int argc, char *argv[])
{
  //initialize Key-Value store--------------------------------------------------
  kv_t **vhost_ptr = (kv_t**)get_env(argv, US_VHOST_DATA), //persistent ptr
       *forum_store = 0; //convenience pointer (var->m instead of (*var)->m)
  
  if (vhost_ptr && !*vhost_ptr)
  {
    *vhost_ptr = (kv_t*)malloc(sizeof(kv_t));
    
    //threads and posts stored here
    kv_init(*vhost_ptr, "forum_store", 1024, 0, 0, 0);
  } forum_store = *vhost_ptr;
  //----------------------------------------------------------------------------
  
  //setup GET and POST variables------------------------------------------------
  char *act = "", *id = "", *title = "", *body = "";
  get_arg("act=",   &act,   argc, argv); //action ('t' or 'p')
  get_arg("id=",    &id,    argc, argv); //id of thread
  get_arg("title=", &title, argc, argv); //title of thread
  get_arg("body=",  &body,  argc, argv); //body of post
  
  char *end = 0;
  u64 int_id = strtoll(id, &end, 10); //string to integer
  if (*end) int_id = 0; //require a numeric ID
  //----------------------------------------------------------------------------
  
  //response sent to browser is stored here-------------------------------------
  //templates are rendered into this buffer
  xbuf_t *reply = get_reply(argv);
  xbuf_cat(reply, base_tpl); //set base template
  //----------------------------------------------------------------------------
  
  //HTTP state of a connection
  http_t *http = (http_t*)get_env(argv, HTTP_HEADERS);
  
  redirect: //simulate HTTP, <meta>, or JavaScript redirect without page reload
  
  //choose what to do based on the value of 'act'-------------------------------
  switch (*act)
  {
    //regarding a post
    case 'p':
    {
      switch (http->h_method) //GET or POST
      {
        //new post--------------------------------------------------------------
        case HTTP_POST:
        {
          //get the thread to which this post belongs
          Thread *thread = (Thread*)kv_get(forum_store, (char*)&int_id, sizeof(int_id));
          
          if (!thread) //thread not found
          {
            xbuf_repl(reply, "<!--tpl-->", http_error(404));
            return 404;
          }
          
          //allocate memory
          Post *post = calloc(1, sizeof(*post));
          
          //initialize members
          xbuf_init(&post->body);
          
          //define members
          post->id = thread->posts.nbr_items + 1;
          xbuf_cat(&post->body, *body ? body : " ");
          
          //add post to thread
          kv_add(&thread->posts, &(kv_item) {
            .key = (char*)&post->id,
            .klen = sizeof(post->id),
            .val = (char*)post,
            .flags = 0,
          });
          
          //setup redirect
          http->h_method = HTTP_GET;
          *act = 't';
          
          goto redirect;
        } break;
        //----------------------------------------------------------------------
      }
    } break;
    
    //regarding a thread
    case 't':
    {
      switch (http->h_method)
      {
        //view a thread---------------------------------------------------------
        case HTTP_GET:
        {
          Thread *thread = (Thread*)kv_get(forum_store, (char*)&int_id, sizeof(int_id));
          
          if (!thread)
          {
            xbuf_repl(reply, "<!--tpl-->", http_error(404));
            return 404;
          }
          
          //replace template variables with dynamic values
          xbuf_repl(reply, "<!--form-->", post_form);
          xbuf_repl(reply, "<!--title-->", thread->title.ptr);
          xbuf_repl(reply, "<!--id-->", id);
          
          //for each post, render its template and insert it into reply
          kv_do(&thread->posts, 0, 0, (kv_proc_t)&list_posts, (void*)reply);
        } break;
        //----------------------------------------------------------------------
        
        //create a thread-------------------------------------------------------
        case HTTP_POST:
        {
          Thread *thread = calloc(1, sizeof(*thread));
          
          xbuf_init(&thread->title);
          kv_init(&thread->posts, "posts", 1024, 0, 0, 0);
          
          thread->id = forum_store->nbr_items + 1;
          xbuf_cat(&thread->title, *title ? title : " ");
          
          //add thread to KV store
          kv_add(forum_store, &(kv_item) {
            .key = (char*)&thread->id,
            .klen = sizeof(thread->id),
            .val = (char*)thread,
            .flags = 0,
          });
          
          http->h_method = HTTP_GET;
          *act = 0;
          
          goto redirect;
        } break;
        //----------------------------------------------------------------------
      }
    } break;
Example #5
0
// ----------------------------------------------------------------------------
// imported functions:
//   get_reply(): get a pointer on the 'reply' dynamic buffer from the server
//     get_env(): get connection's 'environment' variables from the server
//    xbuf_cat(): like strcat(), but it works in the specified dynamic buffer 
//   gif_build(): build an in-memory GIF image from a bitmap and palette
// ----------------------------------------------------------------------------
int main(int argc, char *argv[])
{
   // -------------------------------------------------------------------------
   // build the top of our HTML page
   // -------------------------------------------------------------------------
   static char top[]=
     "<!DOCTYPE HTML>"
     "<html lang=\"en\"><head><title>Captcha</title><meta http-equiv"
     "=\"Content-Type\" content=\"text/html; charset=utf-8\">"
     "<link href=\"/imgs/style.css\" rel=\"stylesheet\" type=\"text/css\">"
     "</head><body style=\"margin:0 16px;\"><br><h2>Captcha for Humans</h2>"
     "<p>Please enter the SUM of all the GREEN FIGURES (not letters) below "
     "(that's twice the same image, just with a different HTML background "
     "- the Data-URI-inlined GIF background is transparent):</p><br>\r\n";

   xbuf_t *reply = get_reply(argv);
   xbuf_ncat(reply, top, sizeof(top) - 1);
   
   // -------------------------------------------------------------------------
   // allocate memory for a raw bitmap
   // -------------------------------------------------------------------------
   const int w = BMP_WIDTH, h = BMP_HEIGHT, wXh = w * h;
   u8 *bmp = (u8*)calloc(CHAR_WIDTH * w, h); 
   if(!bmp) return 503; // service unavailable

   // -------------------------------------------------------------------------
   // render the captcha in our bitmap
   // -------------------------------------------------------------------------
   u32 seed = (u32)getns();
   prnd_t rnd; // pseudo-random generator (period: 1 << 158)
   sw_init(&rnd, seed); // EPOCH time in nano-seconds

   // structure needed by G-WAN's frame buffer routines like dr_text()
   bmp_t img ={ .bmp = bmp, .p = bmp, .bbp = 8, .pen = 1, .bgd = 0, 
                .rect = {0,0, w,h}, .flags = 0, .w = w, .h = h, 
                .x = 0, .y = 0 };
   u32 sum = captcha(&img, &rnd);

   // -------------------------------------------------------------------------
   // build the GIF image, gif_build(0:transparent color index, 0: no comment)
   // -------------------------------------------------------------------------
   u8 pal[] = { 255, 255, 255,  223, 255, 191,  132, 164, 100,  0, 0, 0 };
   const int nbcolors = (sizeof(pal) / sizeof(u8)) / 3; // RGB values

   u8 *gif = (u8*)malloc(CHAR_WIDTH * wXh);
   if(!gif) { free(bmp); return 503; } // service unavailable
   int gln = gif_build(gif, bmp, w, h, pal, nbcolors, 0, 0);

   // -------------------------------------------------------------------------
   // store the base64 encoded GIF in the 'reply' buffer
   // -------------------------------------------------------------------------
   if(gln > 0) // (gln == -1) if gif_build() failed
   {   
      // a real captcha test would only display the first of those two views:
      // (they are shown side-by-side to visualize the background trick)
      xbuf_cat(reply, "<table><tr>\r\n"
                      "<td style=\"background:#dfffbf;\">\r\n");
      u32 img_pos = reply->len;
      xbuf_xcat(reply,
                "<img src=\"data:image/gif;base64,%*B\" alt=\"A tree\" "
                "width=\"%d\" height=\"%d\" /></td>\r\n",
                gln, gif, w + w, h + h); // scale picture
      xbuf_xcat(reply, 
                "<td style=\"background:#84a464;\">%.*s</tr>\r\n</table>\n\r",
                reply->len - img_pos, reply->ptr + img_pos);
   }
   free(gif);
   free(bmp);

   // -------------------------------------------------------------------------
   // close our HTML page
   // -------------------------------------------------------------------------
   xbuf_xcat(reply, 
            "<br>The two sums are: <b>%u</b> and <b>%u</b>... "
            "for the same Captcha image!<br><br>"
            "By just changing the <b>HTML background color</b> (mouse cursor "
            "hovering, previous state or input or shared secret) used for "
            "the transparent GIF Captcha image we can make something simple "
            "for humans become difficult or even completely impossible "
            "for robots.<br><br>"
            "HTML and GIF are served with one single request: the picture"
            " is generated on-the-fly and embedded into the HTML code by "
            " using the base64 encoding (look at the HTML source code)."
            "<br></body></html>", 
            (sum & 0xffff0000) >> 16, 
            sum & 0x0000ffff);

   return 200; // return an HTTP code (200:'OK')
}