Cookieの読込書出しをC言語で作りたいのですが

[上に] [前に] [次に]
チャダ 2000/03/03(金) 16:33:35
はじめまして。なにもかもが超初心者なので
悩みをうまく説明できるか不安なのですが
聞いてください...

Cookieの書き出しと読み取りの関数をC言語で作ってみたのですが、
うまくいかず困っています。

書き出しは、------以下のようなロジックにしてみました。

しかし画面には
Content-type: text〜とか出力されてしまうし、
本当にCookieとやらを発行しているのかさえもわからない状態です

読み取り側はgetenv()で環境変数を取ってきて文字列操作しようとしているのですが、
HTTP_COOKIEにはどうしてもnullが入ってきてしまい、
先に進めません。

なにか解決方法ご存知でしたら教えてください。

ちなみに環境ですが、
パーソナルWebサーバというのを使って、
自分のマシンをWebサーバとして使用しています(?)
ブラウザはIE5です。

--------
#include <stdio.h>
#include <stdlib.h>
#include "SetCookie.h"

void main(void){

char *cname;
char *cvalue;
int  ret;


cname = "KAISUU";
cvalue = "1";

ret = SetCookieData(cname,cvalue);

printf("Content-type: text/html\n\n");
printf("<HTML>\n");
printf("<HEAD>\n");
printf("<TITLE>SetCookieのテスト</TITLE>\n");
printf("</HEAD>\n");
printf("<BODY>\n");
printf("%sの値%sを書き込みました\n\n",cname,cvalue);

printf("</BODY>\n");
printf("</HTML>\n");

return;
}

int SetCookieData(char *cname, char *cvalue){

printf("Set-Cookie: %s=%s; Expires=Man, 19-Jan-98 00:00:00 GMT; path=/; Domain=tyada\n\n",cname,cvalue);

        return 0;

}

S-pore [HomePage] 2000/03/03(金) 16:46:48
> しかし画面には
> Content-type: text〜とか出力されてしまうし、

これは,

> printf("Set-Cookie: %s=%s; Expires=Man, 19-Jan-98 00:00:00 GMT; path=/; Domain=tyada\n\n",cname,cvalue);

の,\n\nで空行を入れてるのでヘッダがそこで終わってしまうからだと思います。
あと,なぜ有効期限が過去なんですか?

> 読み取り側はgetenv()で環境変数を取ってきて文字列操作しようとしているのですが、
> HTTP_COOKIEにはどうしてもnullが入ってきてしまい、
> 先に進めません。

具体的にソースを書いてくれないと悪いとこの指摘のしようがないですが,
上に書いたようにクッキーの有効期限が過去になってるので
クッキーが即消滅していることが原因かもしれません。

チャダ 2000/03/03(金) 17:15:13
S-poreさんお返事ありがとうございます。

確かに有効期限がめちゃくちゃ古いですね。
例題を適当に拾ってきてそのまま何も考えずにいたので。
お恥ずかしい......

読み取り側のソースですが、下に記します。
(こんな長いもの載せていいのかわかりませんが)

ちなみに有効期限を正しい将来のものにしてみたのですが
同じ現象のままです...

----------
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <time.h>
#include "GetCookie.h"

void main(void){
char ***cname;
char ***cvalue;
char *name;
int  ret;
int  i;

printf("Content-type: text/html\n\n");
printf("<HTML>\n");
printf("<HEAD>\n");
printf("<TITLE>GetCookieのテスト</TITLE>\n");
printf("</HEAD>\n");
printf("<BODY>\n");
printf("KAISUUの値です\n\n");

name = "KAISUU";
ret = getCookieData(cname,cvalue,name);
if(ret != -1){
for(i = 0;i < ret;i++){
printf("%sは%sです。\n",cname,cvalue);
}
}
else{
printf("ret=%dでCookieの値取得できませんでした!\n",ret);
}
printf("</BODY>\n");
printf("</HTML>\n");
return;
}

int getCookieData(char ***cname, char ***cvalue, char *name){

        char                    **cookies;
        char                    *record;
        unsigned int    count;

        cookies = getCookies();
        if( cookies == NULL )
                return -1;

        record = getCookieRecord( name, cookies );
        if( record == NULL )
                return -1;

        count = dataSeparater( cname, cvalue, record );
        freeTwoDimArray( cookies );
        if( count < 0 )
                return -1;

        return count;

}

char **getCookies( void ){

        char                    *http_cookie;   /*HTTP_COOKIE*/
        char                    *buf_http_cookie;
        char                    **tmp = NULL;
        char                    buf[BUFSIZE];
        int                             flag = 1;               /*strspl()で用いるフラグ*/
        unsigned int    record_num;

        http_cookie = getenv( "HTTP_COOKIE" );

printf("HTTP_COOKIEは%sです。\n",http_cookie);

        if( http_cookie == NULL )       /*HTTP_COOKIEが存在しない場合*/
                return NULL;

        buf_http_cookie = (char *)malloc( strlen(http_cookie) + 2 );
        if( buf_http_cookie == NULL )
                return NULL;
        sprintf( buf_http_cookie, " %s", http_cookie );

        record_num = 0;
        while( flag ){
                tmp = (char **)realloc( tmp, sizeof(char **) * (record_num + 1) );
                if( tmp == NULL )
                        return NULL;

                *(tmp + record_num) = (char *)malloc( strlen(buf_http_cookie) + 1 );
                if( *(tmp + record_num) == NULL )
                        return NULL;

                flag = strspl( *(tmp + record_num), buf_http_cookie, ';' );
                strspl(buf, *(tmp + record_num), ' ');
                record_num++;
        }

        tmp = (char **)realloc( tmp, sizeof(char **) * (record_num + 1) );
        if( tmp == NULL )
                return NULL;
        *(tmp + record_num) = NULL;             /*終端にNULL*/
        free( buf_http_cookie );

        return tmp;

}

char *getCookieRecord( char *ckname , char **cookies ){

        unsigned int    i;
        char                    *buf = NULL;

        i = 0;
        while( *(cookies + i) ){
                buf = (char *)malloc( strlen(*(cookies + i) + 1) );
                if( buf == NULL )
                        return NULL;
                strspl( buf, *(cookies + i), '=' );
                if( !strcmp( buf, ckname ) ){
                        free( buf );
                        return *(cookies + i);
                }
                i++;
        }
        free( buf );
        return NULL;

}

int dataSeparater( char ***name, char ***value, char *data){

        int count;                              /*ddname=dvalueの組数*/
        char **tmpname = NULL,**tmpval = NULL;  /*dnameとdvalueを格納する2次配列*/
        int flag = 1;

        /*----- 分割&デコード -----*/
        count = 0;
        while( flag ){
                tmpval = (char **)realloc( tmpval, sizeof(char **) * (count + 1));
                if( tmpval == NULL )
                        return -1;
                *(tmpval + count) = (char*)malloc( strlen(data) + 1 );
                if( *(tmpval + count) == NULL )
                        return -1;
                memset( (char *)*(tmpval + count), '\0', sizeof(*(tmpval + count)) );

                tmpname = (char **)realloc( tmpname, sizeof(char **) * (count + 1));
                if( tmpname == NULL )
                        return -1;
                *(tmpname + count) = (char*)malloc( strlen(data) + 1 );
                if( *(tmpname + count) == NULL )
                        return -1;
                memset( (char *)*(tmpname + count), '\0', sizeof(*(tmpname + count)) );

                flag = strspl(*(tmpval + count), data, '&');
                decode(*(tmpval + count));
                strspl(*(tmpname + count), *(tmpval + count), '=');

                count++;
        }
        tmpval = (char **)realloc( tmpval, sizeof(char **) * (count + 1));
        if( tmpval == NULL )
                return -1;
        *(tmpval + count) = NULL;

        tmpname = (char **)realloc( tmpname, sizeof(char **) * (count + 1));
        if( tmpname == NULL )
                return -1;
        *(tmpname + count) = NULL;

        *name = tmpname;
        *value = tmpval;

        return count;
}

int strspl(char *s1, char *s2, char search){

int flag = 1;
char *p = s2, *q = s2; /*s2の位置保存*/

if(s1 == NULL || s2 == NULL)
return 0;

while(*p != search && *p) /*searchに当たる直前までの値を*outに代入 */
*s1++ = *p++;

if(!*p) /*該当する文字無し*/
flag = 0;
*s1 = '\0'; /*s1の最後に\0代入*/
p++; /*区切り文字の分だけスキップ*/
while(*p) /*残りの文字列を、先頭にシフトさせる */
*q++ = *p++;
*q = '\0';
return flag;
}

void freeTwoDimArray(char **Array){

unsigned int i;

if( Array != NULL ){
for( i = 0; *(Array + i); i++ )
free(*(Array + i));

if(Array)
free(Array);
}

return;

}

void decode(char *url){

        register int i, j;

        for(i = 0, j = 0; url[j]; ++i, ++j){
                if((url[i] = url[j]) == '%'){
                        url[i] = tochar(&url[j + 1]);
                        j += 2;
                }
                else if (url[i] == '+')
                url[i] = ' ';
        }
        url[i] = '\0';
}

char tochar(char *x){

        register char c;

        c  = (x[0] >= 'A' ? ((x[0] & 0xdf) - 'A') + 10 : (x[0] - '0'));
        c *= 16;
        c += (x[1] >= 'A' ? ((x[1] & 0xdf) - 'A') + 10 : (x[1] - '0'));
        return(c);
}

とほほ 2000/03/04(土) 02:23:30
管理者のとほほです。

> (こんな長いもの載せていいのかわかりませんが)
あまり長いのは載せないでください。

# ラウンジに行数制限をかけなくちゃ・・・

B-Cus 2000/03/04(土) 07:26:33
> HTTP_COOKIEにはどうしてもnullが入ってきてしまい、
じゃあ set-cookie できていないんでしょう。

読み取り側にもバグがあるように見えます。
  char cookie_data[]="abc=1;def=2";
として、これに対してうまく parse できてますか?

[上に] [前に] [次に]