Link to home
Start Free TrialLog in
Avatar of ItsMe
ItsMe

asked on

set/read cookie with perl

Hi ! How do I set a cookie with a random number and how do I read it again ? Please tell me more about cookies, e.g. where they won't work etc.

regards
ItsMe
Avatar of ItsMe
ItsMe

ASKER

ps: I want to use the cookie to realise an online shop system.
Avatar of ItsMe

ASKER

hi ! perhaps you could write me a source here ? I've been at this pages but I didn't get it to work....

regards
ItsMe
ASKER CERTIFIED SOLUTION
Avatar of Brain2000
Brain2000
Flag of United States of America image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of ItsMe

ASKER

Hi Brain2000,
Ok, thats true and I thought of that, too its a really great way. but how long should I keep an IP free ? what happens if the shopper puts something in his cart (server writes into a file) goes away logs of from the net and another user with the same ip comes into my shop ? Ok, He will have some nice things in his cart .... I think thats really good. And easy ! So you will get the points but just one last question: How would you keep the server clean from files which have been created by not-shopping-people (1. after each order kill ip-file, 2. scan for ???) ? Are many people using the IP method ? I can't understand why somebody should use cookies ....

regards
ItsMe
Well, I have written my own shopping cart to handle this using IP's and here's what has worked for me:

I actually keep a directory with files containing the filename of the IP address.  For example:

\inetpub\wwwroot\cart\
   01/06/00 07:51p   21 192.200.0.51
   01/06/00 07:51p   42 21.2.128.10

In these files are stored any information pertaining to that particular user.  Whether they have ordered something, their form information (i.e. name, address, phone, etc...).  But what determines when this file expires?  That's the next part.

I have a file called holdip.txt which also lives in this cart\ directory.  The file's contents looks like this:

192.200.0.51-85437
21.2.128.10-85432

This is a collection of the IP numbers and the last time they accessed the .CGI program.  I have a #define in the top of my code to determine how many minutes can go by before a particular IP address expires.  When it expires, the IP files in cart\ are deleted.

Since this is a bit complicated, let me post for you the C code that I use to keep the IP addresses updated.  If you're writing in another language, it should be fairly simple to convert over.  If you don't understand what I'm doing in any portion of it, please feel free to ask.


#define IP_TIMEOUT_MINUTES 30

void updateip(void)
{
  FILE *f1,*f2;
  HANDLE myMutex;
  SYSTEMTIME myTime;
  char file1[100],file2[100],temp[100],iptimestamp[100];
  char *ptr;
  int timestamp;
  int keep=0;

  myMutex=CreateMutex(NULL,FALSE,"HOLDIP");
  if(myMutex) {
    WaitForSingleObject(myMutex,INFINITE);

    sprintf(file1,"%s%s.num",savepath,user_ip);
    if((f1=fopen(file1,"r"))!=NULL) {
      temp_file_number=atoi(fgets(temp,sizeof(temp),f1));
      sprintf(temp,"%s-%d.HTM",user_ip,temp_file_number-1);
      unlink(temp);
      fclose(f1);
    }
    else temp_file_number=0;
    if((f1=fopen(file1,"w"))!=NULL) {
      fprintf(f1,"%d",temp_file_number+1);
      fclose(f1);
    }

    GetLocalTime(&myTime);
    timestamp=myTime.wHour*60*60+myTime.wMinute*60+myTime.wSecond;

    sprintf(file1,"%sholdip.txt",savepath);
    sprintf(file2,"%sholdip2.txt",savepath);
    sprintf(iptimestamp,"%s-",user_ip);
    if((f2=fopen(file2,"w"))!=NULL) {
      if((f1=fopen(file1,"r"))!=NULL) {
        while(fgets(temp,sizeof(temp),f1)) {
          if(strncmp(temp,iptimestamp,strlen(iptimestamp))) {
            if(ptr=strchr(temp,'-')) {
              ptr++;
              if(timestamp<atoi(ptr)) {
                timestamp=timestamp+24*60*60;
              }
              if(timestamp-atoi(ptr)<IP_TIMEOUT_MINUTES*60) fprintf(f2,temp);
              else {
                ptr--;
                *ptr=0;
                memmove(temp+strlen(savepath),temp,strlen(temp)+1);
                memcpy(temp,savepath,strlen(savepath));
                unlink(temp);
              }
            }
          }
          else {
            if(ptr=strchr(temp,'-')) {
              ptr++;
              if(timestamp<atoi(ptr)) {
                timestamp=timestamp+24*60*60;
              }
              if(timestamp-atoi(ptr)<IP_TIMEOUT_MINUTES*60) keep=1;
            }
          }
          timestamp=myTime.wHour*60*60+myTime.wMinute*60+myTime.wSecond;
        }
        fclose(f1);
      }
      fprintf(f2,"%s%d\n",iptimestamp,timestamp);
      fclose(f2);
      unlink(file1);
      rename(file2,file1);
      if(!keep) {
        sprintf(temp,"%s%s",savepath,user_ip);
        unlink(temp);
      }
    }
    ReleaseMutex(myMutex);
    CloseHandle(myMutex);
  }
  else {
    f1=fopen("ERROR.TXT","a");
    fprintf(f1,"CAN'T OPEN MUTEX");
    fclose(f1);
  }
}
I need to comment on some other things.  I also keep a filename called IP.num (i.e. 200.0.0.1.num) that holds a sequentially increasing number.  The reason it holds this number is because when you return a web page to a user that is dynamically changing, it seems the only reliable way to make sure it refreshes is to use a different filename.  So I actually have the .CGI pull this unique number and create a temporary unique filename that is sent to the end user.  You'll see some code referencing that above as well.

Also, I use a Mutex, which is a global lock so only one process can run through at a time.  The reason for this is to keep 2 or more processes from accessing the holdip.txt file at the exact same time.  That would be bad if both were trying to read/write to that file simultaneously.  It could cause the file to be written incorrectly.  By using a Mutex, that acts as a siphon to allow only one process through at a time till it releases the Mutex.
Avatar of ItsMe

ASKER

Thank you very much ! I'm using perl and I think I will create temp files e.g. 192-168-100-1.tmp in a secure directory and put in the cart datas. Every time somebody orders I will start a procedure which searches for files older than 3 hours to delete them. I yet don't know how to get the filetime and to check if its older than 5 hrs with perl. If I don't get it to work I will write an external delphi application to handle this problem.
Do you know how to go through all *.tmp files in an directory and how to check the time with perl ?

regards
ItsMe
Avatar of ItsMe

ASKER

PS: I think I will call a special start link which resets the ip-file of the current user. e.g. <a href="http://www.anyserver.de/reset.cgi">to the shop</a> my cgi will catch the ip and overwrite any file.
this prevents me from users which could have the same ip as a shopper before who put something in his cart and left <3 hrs ago ...

All you need is the time of day.  Midnight would be 0 seconds all the way to 23:59:59 which would be 86399 seconds.  Multiply the hour by 60*60, the minutes by 60, and then add the seconds.  If someone comes in and more than 10800 has passed (don't forget to wrap if they pass midnight and wrap to 0).
Avatar of ItsMe

ASKER

isn't it more easy to get the filetime/date add 3 hrs and check if actual time is bigger ?
Oh yes, you're absolutely right.  I never thought of that.  I guess I did it the hard way.  Oops :)  Good call.
Avatar of ItsMe

ASKER

:-)