Пример #1
0
int LoadMyURLDBFile(char * filename)
{
    FILE * pFile;
    pFile = fopen (filename,"r");
    if (pFile!=0)
    {
       char longURL[MAX_LONG_URL_SIZE]={0};
       char shortURL[MAX_TO_SIZE]={0};

       unsigned int i=0;
       while (!feof(pFile))
        {
           memset(longURL,0,MAX_LONG_URL_SIZE);
           memset(shortURL,0,MAX_TO_SIZE);

           int res = fscanf (pFile, "%s\n", longURL);
           if (res!=1) { AmmServer_Warning("error (?) reading longURL (%s) item line %u of file %s ",longURL,i,filename); }
               res = fscanf (pFile, "%s\n", shortURL);
           if (res!=1) { AmmServer_Warning("error (?) reading shortURL (%s) item line %u of file %s ",shortURL,i,filename); }

           Add_MyURL(longURL,shortURL,0 /*We dont want to reappend it :P*/);
           ++i;
        }
     fclose (pFile);
     return 1;
    }

    return 0;
}
Пример #2
0
//This function adds a Resource Handler for the pages stats.html and formtest.html and associates stats , form and their callback functions
void init_dynamic_content()
{
  if (! AmmServer_AddResourceHandler(default_server,&control,"/control.html",webserver_root,4096,0,(void*) &control_callback,SAME_PAGE_FOR_ALL_CLIENTS) )
     { AmmServer_Warning("Failed adding stats page\n"); }

  if (! AmmServer_AddResourceHandler(default_server,&termination,"/terminate.html",webserver_root,4096,0,(void*) &control_callback,SAME_PAGE_FOR_ALL_CLIENTS) )
     { AmmServer_Warning("Failed adding stats page\n"); }


}
Пример #3
0
int AmmServer_RegisterTerminationSignal(void * callback)
{
  TerminationCallback = callback;

  unsigned int failures=0;
  if (signal(SIGINT, AmmServer_GlobalTerminationHandler) == SIG_ERR)  { AmmServer_Warning("AmmarServer cannot handle SIGINT!\n");  ++failures; }
  if (signal(SIGHUP, AmmServer_GlobalTerminationHandler) == SIG_ERR)  { AmmServer_Warning("AmmarServer cannot handle SIGHUP!\n");  ++failures; }
  if (signal(SIGTERM, AmmServer_GlobalTerminationHandler) == SIG_ERR) { AmmServer_Warning("AmmarServer cannot handle SIGTERM!\n"); ++failures; }
  if (signal(SIGKILL, AmmServer_GlobalTerminationHandler) == SIG_ERR) { AmmServer_Warning("AmmarServer cannot handle SIGKILL!\n"); ++failures; }
  return (failures==0);
}
Пример #4
0
//This function adds a Resource Handler for the pages stats.html and formtest.html and associates stats , form and their callback functions
void init_dynamic_content()
{
  AmmServer_AddRequestHandler(default_server,&GET_override,"GET",&request_override_callback);

  unsigned char*  buf = prepare_index_prototype("src/Services/MyBlog/res/index.html",&myblog);

  if (! AmmServer_AddResourceHandler(default_server,&stats,"/index.html",webserver_root,44096,0,&prepare_index,SAME_PAGE_FOR_ALL_CLIENTS) )
     { AmmServer_Warning("Failed adding index page\n"); }

   if (! AmmServer_AddResourceHandler(default_server,&random_chars,"/random.html",webserver_root,4096,0,&prepare_random_content_callback,DIFFERENT_PAGE_FOR_EACH_CLIENT) )
     { AmmServer_Warning("Failed adding random testing page\n"); }

}
Пример #5
0
//This function adds a Resource Handler for the pages stats.html and formtest.html and associates stats , form and their callback functions
void init_dynamic_content()
{

  if (! AmmServer_AddResourceHandler(default_server,&searchContext,"/search.html",webserver_root,4096,0,&search_callback,SAME_PAGE_FOR_ALL_CLIENTS) )
     { AmmServer_Warning("Failed adding stats page\n"); }

  if (! AmmServer_AddResourceHandler(default_server,&indexContext,"/index.html",webserver_root,4096,0,&prepare_index_content_callback,SAME_PAGE_FOR_ALL_CLIENTS) )
     { AmmServer_Warning("Failed adding stats page\n"); }

   if (! AmmServer_AddResourceHandler(default_server,&logoContext,"/search.png",webserver_root,4096,0,&prepare_logo_content_callback,DIFFERENT_PAGE_FOR_EACH_CLIENT) )
     { AmmServer_Warning("Failed adding random testing page\n"); }

   if (! AmmServer_AddResourceHandler(default_server,&faviconContext,"/favicon.ico",webserver_root,4096,0,&favicon_callback,DIFFERENT_PAGE_FOR_EACH_CLIENT) )
     { AmmServer_Warning("Failed adding random testing page\n"); }


}
Пример #6
0
int AmmServer_AddResourceHandler
     ( struct AmmServer_Instance * instance,
       struct AmmServer_RH_Context * context,
       const char * resource_name ,
       const char * web_root,
       unsigned int allocate_mem_bytes,
       unsigned int callback_every_x_msec,
       void * callback,
       unsigned int scenario
    )
{
   if ( context->requestContext.content!=0 )
    {
      AmmServer_Warning("Context in AmmServer_AddResourceHandler for %s appears to have an already initialized memory part\n",resource_name);
      AmmServer_Warning("Make sure that you are using a seperate context for each AmmServer_AddResourceHandler call you make..\n");
    }
   memset(context,0,sizeof(struct AmmServer_RH_Context));
   strncpy(context->web_root_path,web_root,MAX_FILE_PATH);
   strncpy(context->resource_name,resource_name,MAX_RESOURCE);
   context->requestContext.instance=instance; // Remember the instance that created this..
   context->requestContext.MAXcontentSize=allocate_mem_bytes;
   context->callback_every_x_msec=callback_every_x_msec;
   context->last_callback=0; //This is important because a random value here will screw up things with callback_every_x_msec..
   context->callback_cooldown=0;
   context->RH_Scenario = scenario;

   if ( allocate_mem_bytes>0 )
    {
       context->requestContext.content = (char*) malloc( sizeof(char) * allocate_mem_bytes );
       if (context->requestContext.content==0) { AmmServer_Warning("Could not allocate space for request Context"); }
    }

   context->dynamicRequestCallbackFunction=callback;
   if (callback==0) { AmmServer_Warning("No callback passed for a new AmmServer_AddResourceHandler "); }


   int returnValue = cache_AddMemoryBlock(instance,context);

   if (!returnValue)
   {
     AmmServer_Error("Failed adding new resource handler\n Resource name `%s` will be unavailable\n",resource_name);
   }

  return returnValue;
}
Пример #7
0
unsigned long Add_MyURL(char * longURL,char * shortURL,int saveit)
{
  int shortURL_AlreadyExists=0;
  Find_longURL(shortURL,&shortURL_AlreadyExists);
  if (shortURL_AlreadyExists) { return 0; }

  if (loaded_links>=MAX_LINKS) { return 0; }
  allocateLinksIfNeeded();

  unsigned int long_url_length = strlen(longURL);
  if (long_url_length>=MAX_LONG_URL_SIZE) { return 0; }
  unsigned int sort_url_length = strlen(shortURL);
  if (sort_url_length>=MAX_TO_SIZE) { return 0; }

  pthread_mutex_lock (&db_addIDLock); // LOCK PROTECTED OPERATION -------------------------------------------
  //it might not seem like it but here we are doing two seperate operations
  //first we give our_index the loaded_links value , and then we increment loaded_links
  //of course this is a potential race condition where two threads assign themselves the same link
  //and we have an empty record after that , solved using a lock protection
  unsigned int our_index=loaded_links++;
  pthread_mutex_unlock (&db_addIDLock); // LOCK PROTECTED OPERATION -------------------------------------------

  links[our_index].longURL = ( char * ) malloc (sizeof(char) * (long_url_length+1) );  //+1 for null termination
  if ( links[our_index].longURL == 0 ) { AmmServer_Warning("Could not allocate space for a new string \n "); return 0; }
  links[our_index].shortURL = ( char * ) malloc (sizeof(char) * (sort_url_length+1) ); //+1 for null termination
  if ( links[our_index].shortURL == 0 ) { AmmServer_Warning("Could not allocate space for a new string \n "); return 0; }

  links[our_index].shortURLHash=hashURL(shortURL);

  strncpy(links[our_index].longURL,longURL,long_url_length);
  links[our_index].longURL[long_url_length]=0;  // null terminator :P

  strncpy(links[our_index].shortURL,shortURL,sort_url_length);
  links[our_index].shortURL[sort_url_length]=0;  // null terminator :P

  if (saveit) { Append2MyURLDBFile(db_file,longURL,shortURL); }

  if ( REGROUP_AFTER_X_UNSORTED_LINKS <= loaded_links-sorted_links )
  {
      ResortDB(db_file,links,loaded_links);
  }

  return 1;
}
Пример #8
0
int closeAmmarServer()
{
    //Delete dynamic content allocations and remove stats.html and formtest.html from the server
    close_dynamic_content();

    //Stop the server and clean state
    AmmServer_Stop(default_server);
    AmmServer_Warning("Ammar Server stopped\n");
    return 1;
}
Пример #9
0
//This call , calls  callback every time a request hits the server..
//The outer layer of the server can do interesting things with it :P
//request_type is supposed to be GET , HEAD , POST , CONNECT , etc..
int AmmServer_AddRequestHandler(struct AmmServer_Instance * instance,struct AmmServer_RequestOverride_Context * RequestOverrideContext,const char * request_type,void * callback)
{
  if ( (instance==0)||(RequestOverrideContext==0)||(request_type==0)||(callback==0) ) { return 0; }
  strncpy( RequestOverrideContext->requestHeader , request_type , 64 /*limit declared on AmmServerlib.h*/) ;
  RequestOverrideContext->request=0;

  instance->clientRequestHandlerOverrideContext = RequestOverrideContext;
  RequestOverrideContext->request_override_callback = callback;

  AmmServer_Warning("AmmServer_AddRequestHandler could potentially be buggy\n");

  return 1;
}
Пример #10
0
int main(int argc, char *argv[])
{
    printf("\nAmmar Server %s starting up..\n",AmmServer_Version());
    //Check binary and header spec
    AmmServer_CheckIfHeaderBinaryAreTheSame(AMMAR_SERVER_HTTP_HEADER_SPEC);
    //Register termination signal for when we receive SIGKILL etc
    AmmServer_RegisterTerminationSignal(&close_dynamic_content);

    char bindIP[MAX_IP_STRING_SIZE];
    strcpy(bindIP,"0.0.0.0");

    unsigned int port=DEFAULT_BINDING_PORT;

    //Kick start AmmarServer , bind the ports , create the threads and get things going..!
    default_server = AmmServer_StartWithArgs(
                                             "MySearch",
                                              argc,argv , //The internal server will use the arguments to change settings
                                              //If you don't want this look at the AmmServer_Start call
                                              bindIP,
                                              port,
                                              0, /*This means we don't want a specific configuration file*/
                                              webserver_root,
                                              templates_root
                                              );


    if (!default_server) { AmmServer_Error("Could not start server , shutting down everything.."); exit(1); }

    //Create dynamic content allocations and associate context to the correct files
    init_dynamic_content();
    //stats.html and formtest.html should be availiable from now on..!

         while ( (AmmServer_Running(default_server))  )
           {
             //Main thread should just sleep and let the background threads do the hard work..!
             //In other applications the programmer could use the main thread to do anything he likes..
             //The only caveat is that he would takeup more CPU time from the server and that he would have to poll
             //the AmmServer_Running() call once in a while to make sure everything is in order
             //usleep(60000);
             sleep(1);
           }

    //Delete dynamic content allocations and remove stats.html and formtest.html from the server
    close_dynamic_content();

    //Stop the server and clean state
    AmmServer_Stop(default_server);
    AmmServer_Warning("Ammar Server stopped\n");
    return 0;
}
Пример #11
0
int ResortDB(char * db_file,struct URLDB * links,unsigned int loaded_links)
{
  if ( !isURLDBSorted() )
        {
           AmmServer_Warning("URLDB is not sorted Sorting it now..!\n");
           qsort(links, loaded_links , sizeof(struct URLDB), struct_cmp_urldb_items);

           if ( !isURLDBSorted() ) { AmmServer_Warning("Could not sort URLDB ..! :( , exiting \n");
                                     return 0;
                                   } else
                                   {
                                     AmmServer_Success("Sorted URLDB \n");
                                     if ( ReWriteMyURLDBFile(db_file,links,loaded_links) )
                                     {
                                        AmmServer_Success("Saved db file \n");
                                     }
                                   }
        } else
        {
          AmmServer_Success("Presorted URLDB \n");
        }
   return 1;
}
Пример #12
0
char * getPointerToGETItemValue(struct AmmServer_DynamicRequest * rqst,const char * nameToLookFor,unsigned int * pointerLength)
{
 const struct GETRequestContent * p = getGETItemFromName(rqst,nameToLookFor);

 if (p!=0)
 {
       //AmmServer_Success("getPointerToPOSTItemValue(%s) success => %p \n",nameToLookFor,p->value);
       *pointerLength = p->valueSize;
       return p->value;
 }

 AmmServer_Warning("getPointerToPOSTItemValue called but could not find name=`%s` \n",nameToLookFor);
 *pointerLength=0;
 return 0;
}
Пример #13
0
unsigned int allocateLinksIfNeeded()
{
  unsigned int makeAnAllocation=0;
  if (allocated_links>=MAX_LINKS)  { AmmServer_Warning("Reached constraint on links , will not commit more memory\n"); return 0;  }
  if (loaded_links>=allocated_links)  { makeAnAllocation=1; }

  if (makeAnAllocation)
  {
      fprintf(stderr,"Reallocating -> %u records \n",allocated_links+LINK_ALLOCATION_STEP);
      struct URLDB * newlinks = realloc(links, sizeof(struct URLDB) * (allocated_links+LINK_ALLOCATION_STEP) );
      if (newlinks!=0)
         {
            links=newlinks;
            memset(links+allocated_links,0,LINK_ALLOCATION_STEP);
            allocated_links+=LINK_ALLOCATION_STEP;
            return 1;
         }
  }

  return 0;
}
Пример #14
0
//Binary Search
inline unsigned int Find_longURL(char * shortURL,int * found)
{
  #if USE_BINARY_SEARCH
  *found = 0;
  if (shortURL==0) { return 0; }
  if (loaded_links==0) { return 0; }

  if (sorted_links!=0)
  {
   unsigned long our_hash = hashURL(shortURL);
   unsigned int binarySearchLastElement = sorted_links;
   unsigned int beg=0,mid=0,fin=binarySearchLastElement-1;
   while ( beg <= fin )
   {
     mid=(unsigned int) beg + ( (fin-beg)/2 );
     if (mid >= binarySearchLastElement)
        { AmmServer_Error("Binary Search overflowed ( beg %u mid %u fin %u ) , binarySearchLastElement %u \n",beg,mid,fin,binarySearchLastElement); break; } else
     if (our_hash<links[mid].shortURLHash) { fin=mid-1; } else
     if (our_hash>links[mid].shortURLHash) { beg=mid+1; } else
                                           {
                                             *found = 1;
                                             AmmServer_Success("Found %s using binary search\n",shortURL);
                                             return mid;
                                           }
   }
  }
  //TODO : Remove this message in the future -------------
  AmmServer_Warning("Binary Search couldn't find result , extending search to unsorted list\n");
  return Find_longURLSerial(shortURL,found);
  //----------------------------------------
  #else // USE_BINARY_SEARCH
   return Find_longURLSerial(shortURL,found);
  #endif

  return 0;
}
Пример #15
0
int finalizeGenericGETField(
                             struct HTTPHeader * output,
                             struct GETRequestContent * target ,
                             unsigned int * targetNumber ,
                             char * value,
                             unsigned int valueLength
                           )
{
  //-----------------------------------------------------------------------------------
  if (value == 0)        { AmmServer_Warning("finalizeGenericGETField Value is not set\n");         return 0; }
  if (valueLength == 0)  { AmmServer_Warning("Value Length is not set\n");  return 0; }
  if (target == 0)       { AmmServer_Warning("Target is not set\n");        return 0; }
  if (output == 0)       { AmmServer_Warning("Output is not set\n");        return 0; }
  if (targetNumber == 0) { AmmServer_Warning("Target Number is not set\n"); return 0; }
  //-----------------------------------------------------------------------------------

  *targetNumber=0;
  char * GETPtr = value;

  unsigned int GETPtrLength = valueLength;
  char * GETPtrEnd = GETPtr + GETPtrLength;

  //AmmServer_Warning("GET Request %s has %u bytes of stuff..\n",GETPtr ,GETPtrLength);

  char * startOfPTR=GETPtr;


  unsigned int state = FOUND_NOTHING;
  while (GETPtr<GETPtrEnd)
  {
    if ( (*GETPtr==10) || (*GETPtr==13) || (*GETPtr==0) )
    {
      if (state==FOUND_NOTHING)
        {
          //We found no payload..
          break;
        } else
      if (state==SEEKING_NAME)
        {
          //Last Item was a name with no value
          target[*targetNumber].name=startOfPTR;
          target[*targetNumber].value=0;
          *GETPtr=0; //Null Terminate
          *targetNumber+=1;
          break;
        } else
      if (state==SEEKING_VALUE)
        {
          //We reached the end having found a name(which is already set) and a value..!
          target[*targetNumber].value=startOfPTR;
          *GETPtr=0; //Null Terminate

          //fprintf(stderr,"We finished string searching for a value so it is found value %s\n",startOfPTR);
          *targetNumber+=1;
          break;
        }
    } else
    {
      //fprintf(stderr,"GET -> %c \n",*GETPtr);
      if (state == FOUND_NOTHING) { state=SEEKING_NAME; }

      if (*GETPtr=='=')
      {

       //We found a value
       if (state==SEEKING_NAME)
        {
          target[*targetNumber].name=startOfPTR;
          target[*targetNumber].value=0;
          *GETPtr=0;
          //fprintf(stderr,"We finished a name %s\n",startOfPTR);

          state=SEEKING_VALUE;
          startOfPTR=GETPtr+1;
        }
      } else
      if (*GETPtr=='&')
      {
       //We found a value
       if (state==SEEKING_NAME)
        {
          target[*targetNumber].name=startOfPTR;
          target[*targetNumber].value=0;
          *targetNumber+=1;

          *GETPtr=0; //Null Terminate
          startOfPTR=GETPtr+1;
        } else
       if (state==SEEKING_VALUE)
        {
          target[*targetNumber].value=startOfPTR;
          *targetNumber+=1;

          *GETPtr=0; //Null Terminate
          state=SEEKING_NAME;
          startOfPTR=GETPtr+1;
        }
      }

    }


    ++GETPtr;
  }

  //Final ( or only value )
  if (state==SEEKING_VALUE)
        {
          //We reached the end having found a name(which is already set) and a value..!
          target[*targetNumber].value=startOfPTR;
          *GETPtr=0; //Null Terminate

          //fprintf(stderr,"We finished string searching for a value so it is found value %s\n",startOfPTR);
          *targetNumber+=1;
        }

  //Mark that all of the get items here point on RAW and need update on realloc
  unsigned int i=0;
  for (i=0; i<*targetNumber; i++)
  {
     target[i].reallocateOnHeaderRAWResize=1;

     //TODO strip HTML characters here..
     //StripHTMLCharacters_Inplace(output->GETquery,0 /* 0 = Disregard dangerous bytes , Safety OFF*/); // <- This call converts char sequences like %20 to " " and %00 to \0 disregarding any form of safety , ( since it is a raw var )

     target[i].nameSize  = strlen(target[i].name);
     target[i].valueSize = strlen(target[i].value);
  }

/*
  AmmServer_Success("A total of %u GET Items \n",*targetNumber);
  for (i=0; i<*targetNumber; i++)
  {
     fprintf(stderr,"GET Item %u ------------------ \n",i);
     fprintf(stderr,"name = %s \n",target[i].name);
     fprintf(stderr,"value = %s \n",target[i].value);
     fprintf(stderr,"-------------------------------- \n",i);
  }
*/

 return 1;
}