xLib/https_tool.c File Reference

HTTPS ツールライブラリ. More...

#include "https_tool.h"
Include dependency graph for https_tool.c:

Go to the source code of this file.

Functions

int send_https_header (int sofd, SSL *ssl, tList *pp, int mode)
int send_https_Buffer (int sofd, SSL *ssl, tList *pl, Buffer *buf)
int send_https_file (int sofd, SSL *ssl, tList *pl, const char *fname)
int recv_https_header (int sofd, SSL *ssl, tList **pl, int *len, int tm, FILE *fp, int *state)
int recv_https_content (int sofd, SSL *ssl, Buffer *buf, int len, int tm, FILE *fp, int *state)
int recv_https_chunked (int sofd, SSL *ssl, Buffer *buf, int tm, FILE *fp, int *state)
int recv_https_chunked_remain (int sofd, SSL *ssl, Buffer *buf, int chnksz, int tm)
int recv_https_closed (int sofd, SSL *ssl, Buffer *buf, int tm, FILE *fp)
int recv_https_Buffer (int sofd, SSL *ssl, tList **pl, Buffer *buf, int tsecond, int *hdonly, int *state, int nochunk)
int recv_https_file (int sofd, SSL *ssl, tList **pl, const char *fname, const char *wdir, int tsecond, int *hdonly, int *state)
int save_https_xml (int cofd, SSL *ssl, tList **pl, tXML **xml, char **recvfn, const char *wdir, int timeout, int *state)

Detailed Description

Author:
Fumi.Iseki (C)

Definition in file https_tool.c.


Function Documentation

int recv_https_Buffer ( int  sofd,
SSL *  ssl,
tList **  pl,
Buffer buf,
int  tsecond,
int *  hdonly,
int *  state,
int  nochunk 
)

int recv_https_Buffer(int sofd, SSL* ssl, tList** pl, Buffer* buf, int tsecond, int* hdonly, int* state, int nochunk)

HTTPSメッセージを受信して,Buffer変数 *bufに保存する.gzipのエンコード処理は行わない. bufのバッファ領域は予め確保されていること.

Parameters:
sofd 接続相手へのソケット
ssl 接続相手への SSLソケット.SSL通信でない場合は NULL を指定.
[out] *pl 受信したヘッダが格納されるリストへのポインタ.必要ないなら NULLでも良い.
[out] buf コンテンツを格納する Buffer変数へのポインタ.バッファ部は予め確保して置く.
tsecond 最初の受信までのタイムアウト(s)
[out] hdonly データがヘッダのみの場合は TRUE, コンテンツもある場合は FALSE.NULLを指定しても良い.
[out] state サーバとの接続状態.接続中なら TRUE.切断した場合は FALSE.NULLを指定しても良い.
nochunk chunkデータを処理しない
Return values:
0以上 受信したコンテンツのサイズ(Byte)
JBXL_SSL_RECV_ERROR 受信エラー
JBXL_ARGS_ERROR buf エラー
JBXL_NET_RECV_TIMEOUT タイムアウトした.

Definition at line 541 of file https_tool.c.

References add_protocol_header, Buffer::buf, clear_Buffer(), copy_Buffer(), del_tList(), delete_protocol_header, FALSE, free_Buffer(), freeNull, HDLIST_CONTENTS_KEY, HTTP_HEADER_CHUNKED, HTTP_HEADER_UNKNOWN_LEN, HTTP_UNKNOWN_METHOD, is_http_header_field(), itostr_ts(), JBXL_ARGS_ERROR, recv_https_chunked(), recv_https_closed(), recv_https_content(), recv_https_header(), search_protocol_header(), TRUE, and Buffer::vldsz.

00542 {
00543     int    cc=0, hs, len;
00544     int    connect;
00545     Buffer cnt;
00546     tList* lp;
00547     
00548     if (buf==NULL || buf->buf==NULL) return JBXL_ARGS_ERROR;
00549     if (hdonly!=NULL) *hdonly = FALSE;
00550 
00551     clear_Buffer(buf);
00552 
00553     // ヘッダの受信
00554     hs = recv_https_header(sofd, ssl, &lp, &len, tsecond, NULL, &connect);
00555     if (state!=NULL) *state = connect;
00556     if (hs<=0) return hs;                                           // エラー
00557     if (len==0 || len==HTTP_HEADER_UNKNOWN_LEN) {                   // ヘッダのみ
00558         if (hdonly!=NULL) *hdonly = TRUE;
00559         if (pl!=NULL) *pl = lp;
00560         else del_tList(&lp);
00561         return hs;
00562     }
00563 
00564     // ヘッダ中に紛れ込んだコンテンツの取り出し
00565     cnt = search_protocol_header(lp, (char*)HDLIST_CONTENTS_KEY, 1);
00566     if (cnt.buf!=NULL) {
00567         cc = cnt.vldsz;
00568         hs = hs - cc;
00569         copy_Buffer(&cnt, buf);
00570         free_Buffer(&cnt);
00571     }
00572 
00573     if (lp!=NULL && lp->ldat.id==HTTP_UNKNOWN_METHOD) {             // not HTTP
00574         *pl = lp;
00575         return cc;
00576     }
00577 
00578     // コンテンツの受信
00579     if (connect) {
00580         if (len>0) {
00581             cc = recv_https_content(sofd, ssl, buf, len, tsecond, NULL, &connect);
00582         }
00583         else if (len==HTTP_HEADER_CHUNKED) {
00584             connect = HTTP_HEADER_CHUNKED;
00585             if (!nochunk) {
00586                 cc = recv_https_chunked(sofd, ssl, buf, tsecond, NULL, &connect);
00587             }
00588         }
00589         else {  //if (len==HTTP_HEADER_CLOSED_SESSION) {
00590             cc = recv_https_closed(sofd, ssl, buf, tsecond, NULL);
00591             connect = FALSE;
00592         }
00593     }
00594 
00595     // for Chunked
00596     if (!nochunk && is_http_header_field(lp, (char*)"Transfer-Encoding", (char*)"chunked", 1)) {
00597         delete_protocol_header(&lp, (char*)"Transfer-Encoding", 0); 
00598         char* str = itostr_ts(cc);
00599         add_protocol_header(lp, (char*)"Content-Length", str);   
00600         freeNull(str);
00601     }
00602 
00603     if (pl!=NULL) *pl = lp;
00604     else del_tList(&lp);
00605 
00606     if (cc>0) cc = cc + hs;
00607 
00608     if (state!=NULL) *state = connect;
00609     return cc;
00610 }

Here is the call graph for this function:

int recv_https_chunked ( int  sofd,
SSL *  ssl,
Buffer buf,
int  tm,
FILE *  fp,
int *  state 
)

int recv_https_chunked(int sofd, SSL* ssl, Buffer* buf, int tm, FILE* fp, int* state)

HTTPメッセージで recv_https_header() で受信したヘッダに引き続いて,Chunkモードのコンテンツデータを受信する.

fp がNULLでなければ,受信データ(コンテンツ)はファイルにも保存される.

Parameters:
sofd 接続相手へのソケット
ssl 接続相手への SSLソケット.SSL通信でない場合は NULL を指定.
[in,out] buf 全コンテンツを保存する変数.最初に,recv_https_header()で受信したコンテンツ部分を入れて置く.
tm タイムアウト秒数.
fp 受信したコンテンツを保存するファイルディスクリプタ.NULLなら保存しない.
[out] state サーバとの接続状態.接続中なら TRUE.切断した場合は FALSE.NULLを指定しても良い.
Return values:
0以上 全コンテンツのサイズ(Byte).recv_https_header()で受信したコンテンツ部分を含む.
0未満 エラー

Definition at line 369 of file https_tool.c.

References Buffer::buf, cat_Buffer(), clear_Buffer(), FALSE, free_Buffer(), get_chunked_size(), make_Buffer(), recv_https_chunked_remain(), RECVBUFSZ, ssl_tcp_recv_Buffer_wait(), TRUE, and Buffer::vldsz.

Referenced by recv_https_Buffer(), and recv_https_file().

00370 {
00371     int cc, sz, i;
00372     int chnksz, hdsz, tlsz;
00373     if (state!=NULL) *state = TRUE;
00374 
00375     Buffer tmp = make_Buffer(RECVBUFSZ);
00376 
00377     sz = buf->vldsz;
00378     if (sz<=0) {    // chunk のサイズを含んだデータを読み込む
00379         cc = ssl_tcp_recv_Buffer_wait(sofd, ssl, &tmp, tm);
00380         if (cc<=0) {
00381             if (state!=NULL) *state = FALSE;
00382             free_Buffer(&tmp);
00383             return cc;
00384         }
00385     }
00386     else {          // 既にコンテンツがある場合は tmpへ移動 
00387         cat_Buffer(buf, &tmp);
00388         clear_Buffer(buf);
00389     }
00390 
00391     //
00392     chnksz = sz = get_chunked_size((char*)tmp.buf, &hdsz, &tlsz);
00393 
00394     while (chnksz>0) {
00395         //
00396         if (chnksz+hdsz+tlsz > tmp.vldsz) {
00397             cc = recv_https_chunked_remain(sofd, ssl, &tmp, chnksz+hdsz+tlsz, tm);
00398             if (cc<=0) {
00399                 sz = cc;
00400                 break;
00401             }
00402         }
00403     
00404         Buffer cat = tmp;
00405         cat.buf = tmp.buf + hdsz;
00406         cat.vldsz = chnksz;
00407         cat_Buffer(&cat, buf);
00408         //tmp.buf[tmp.vldsz] = '\0';
00409 
00410         // 次の chunk用にデータをつめる
00411         for (i=0; i<tmp.vldsz-chnksz-hdsz-tlsz; i++) {
00412             tmp.buf[i] = tmp.buf[chnksz + hdsz + tlsz + i];
00413         }
00414         tmp.vldsz = tmp.vldsz - chnksz - hdsz - tlsz;
00415         //tmp.buf[tmp.vldsz] = '\0';
00416 
00417         if (tmp.vldsz==0) {
00418             cc = ssl_tcp_recv_Buffer_wait(sofd, ssl, &tmp, tm);
00419             if (cc<=0) {
00420                 sz = cc;
00421                 break;
00422             }
00423         }
00424         chnksz = get_chunked_size((char*)tmp.buf, &hdsz, &tlsz);
00425         sz += chnksz;
00426     }
00427 
00428     if (fp!=NULL) fwrite(buf->buf, buf->vldsz, 1, fp);
00429 
00430     free_Buffer(&tmp);
00431     return sz;
00432 }

Here is the call graph for this function:

Here is the caller graph for this function:

int recv_https_chunked_remain ( int  sofd,
SSL *  ssl,
Buffer buf,
int  chnksz,
int  tm 
)

int recv_https_chunked_remain(int sofd, SSL* ssl, Buffer* buf, int chnksz, int tm)

chunk の残りのデータを読み込む.次の chunkのデータも読み込まれる可能性がある.

Parameters:
sofd 接続相手へのソケット
ssl 接続相手への SSLソケット.SSL通信でない場合は NULL を指定.
[in,out] buf 残りのコンテンツを保存する変数.最初に,recv_http_header()で受信したコンテンツ部分を入れて置く.
chnksz 最低限読み込むべきサイズ.chunkのサイズ
tm タイムアウト秒数.
Return values:
1以上 読み込んだコンテンツのサイズ(Byte).recv_http_header()で受信したコンテンツ部分を含む.
0以下 エラー

Definition at line 450 of file https_tool.c.

References cat_Buffer(), free_Buffer(), make_Buffer(), RECVBUFSZ, ssl_tcp_recv_Buffer_wait(), and Buffer::vldsz.

Referenced by recv_https_chunked().

00451 {
00452     int cc = 0;
00453     int sz = buf->vldsz;
00454     if (chnksz<=sz) return 0;
00455 
00456     Buffer rcv = make_Buffer(RECVBUFSZ);
00457 
00458     while (chnksz>sz) {
00459         //memset(rcv.buf, 0, cc);
00460         cc = ssl_tcp_recv_Buffer_wait(sofd, ssl, &rcv, tm);
00461         if (cc<=0) {
00462             sz = cc;
00463             break;
00464         }
00465         cat_Buffer(&rcv, buf);
00466         sz += cc;
00467     }
00468 
00469     free_Buffer(&rcv);
00470     return sz;
00471 }

Here is the call graph for this function:

Here is the caller graph for this function:

int recv_https_closed ( int  sofd,
SSL *  ssl,
Buffer buf,
int  tm,
FILE *  fp 
)

int recv_https_closed(int sofd, SSL* ssl, Buffer* buf, int tm, FILE* fp)

HTTPSメッセージで recv_https_header() で受信したヘッダに引き続いて,長さ不明のコンテンツデータを受信する. この命令で残りの全てのヘッダを読み込む.

fp がNULLでなければ,受信データ(コンテンツ)はファイルにも保存される.

Parameters:
sofd 接続相手へのソケット
ssl 接続相手への SSLソケット.SSL通信でない場合は NULL を指定.
[in,out] buf 全コンテンツを保存する変数.最初に,recv_https_header()で受信したコンテンツ部分を入れて置く.
tm タイムアウト秒数.
fp 受信したコンテンツを保存するファイルディスクリプタ.NULLなら保存しない.
Return values:
0以上 全コンテンツのサイズ(Byte).recv_https_header()で受信したコンテンツ部分を含む.
0未満 エラー

Definition at line 492 of file https_tool.c.

References Buffer::buf, cat_Buffer(), free_Buffer(), JBXL_NET_RECV_TIMEOUT, make_Buffer(), recv_wait(), RECVBUFSZ, ssl_tcp_recv_Buffer_wait(), and Buffer::vldsz.

Referenced by recv_https_Buffer(), and recv_https_file().

00493 {
00494     int cc, sz, tout;
00495     Buffer rcv;
00496 
00497     sz = buf->vldsz;
00498 
00499     rcv = make_Buffer(RECVBUFSZ);
00500     while ((tout=recv_wait(sofd, tm))) {
00501         cc = ssl_tcp_recv_Buffer_wait(sofd, ssl, &rcv, tm);
00502         if (cc>0) {
00503             if (fp!=NULL) fwrite(rcv.buf, cc, 1, fp);
00504             cat_Buffer(&rcv, buf);
00505             sz += cc;
00506         }
00507         else {
00508             break;
00509         }
00510         //memset(rcv.buf, 0, cc);
00511     }
00512     free_Buffer(&rcv);
00513 
00514     if (!tout) return JBXL_NET_RECV_TIMEOUT;
00515 
00516     return sz;
00517 }

Here is the call graph for this function:

Here is the caller graph for this function:

int recv_https_content ( int  sofd,
SSL *  ssl,
Buffer buf,
int  len,
int  tm,
FILE *  fp,
int *  state 
)

int recv_https_content(int sofd, SSL* ssl, Buffer* buf, int len, int tm, FILE* fp, int* state)

HTTPSメッセージで recv_https_header() で受信したヘッダに引き続いて,コンテンツを受信する.

fp がNULLでなければ,受信データ(コンテンツ)はファイルにも保存される.

Parameters:
sofd 接続相手へのソケット
ssl 接続相手への SSLソケット.SSL通信でない場合は NULL を指定.
[in,out] buf 全コンテンツを保存する変数.最初に,recv_https_header()で受信したコンテンツ部分を入れて置く.
len 受信したヘッダの "Content-Length" の値.受信データのサイズのチェックに使用する.
tm タイムアウト秒数.
fp 受信したコンテンツを保存するファイルディスクリプタ.NULLなら保存しない.
[out] state サーバとの接続状態.接続中なら TRUE.切断した場合は FALSE.NULLを指定しても良い.
Return values:
0以上 全コンテンツのサイズ(Byte).recv_https_header()で受信したコンテンツ部分を含む.
0未満 エラー

Definition at line 319 of file https_tool.c.

References Buffer::buf, cat_Buffer(), FALSE, free_Buffer(), make_Buffer(), RECVBUFSZ, ssl_tcp_recv_Buffer_wait(), TRUE, and Buffer::vldsz.

Referenced by recv_https_Buffer(), and recv_https_file().

00320 {
00321     int cc, sz;
00322     Buffer rcv;
00323 
00324     if (state!=NULL) *state = TRUE;
00325     sz = buf->vldsz;
00326     if (sz>0 && fp!=NULL) fwrite(buf->buf, sz, 1, fp);
00327 
00328     // コンテンツの残りを受信
00329     rcv = make_Buffer(RECVBUFSZ);
00330     while(sz<len) {
00331         //
00332         cc = ssl_tcp_recv_Buffer_wait(sofd, ssl, &rcv, tm);
00333         if (cc>0) {
00334             if (fp!=NULL) fwrite(rcv.buf, cc, 1, fp);
00335             cat_Buffer(&rcv, buf);
00336             sz += cc;
00337         }
00338         else {
00339             if (state!=NULL) *state = FALSE;
00340             sz = cc;
00341             break;
00342         }
00343         //memset(rcv.buf, 0, cc);
00344     }
00345 
00346     free_Buffer(&rcv);
00347     return sz;
00348 }

Here is the call graph for this function:

Here is the caller graph for this function:

int recv_https_file ( int  sofd,
SSL *  ssl,
tList **  pl,
const char *  fname,
const char *  wdir,
int  tsecond,
int *  hdonly,
int *  state 
)

int recv_https_file(int sofd, SSL* ssl, tList** pl, const char* fname, const char* wdir, int tsecond, int* hdonly, int* state)

HTTPSメッセージを受信して,コンテンツをファイルに保存する.Encodingが gzipの場合は展開する.

Parameters:
sofd 接続相手へのソケット
ssl 接続相手への SSLソケット.SSL通信でない場合は NULL を指定.
[out] *pl 受信したヘッダが格納されるリストへのポインタ.
fname 保存するファイル名
wdir 作業用ディレクトリを指定.NULLの場合は /tmp になる.
tsecond 最初の受信までのタイムアウト(s)
[out] hdonly データがヘッダのみの場合は TRUE, コンテンツもある場合は FALSE.NULLを指定しても良い.
[out] state サーバとの接続状態.接続中なら TRUE.切断した場合は FALSE.NULLを指定しても良い.
Return values:
1以上 受信したファイルのサイズ(Byte)(ヘッダを含む)
0 正常切断
JBXL_SSL_RECV_ERROR 受信エラー
JBXL_NET_RECV_TIMEOUT タイムアウトした.

Definition at line 632 of file https_tool.c.

References add_protocol_header, Buffer::buf, copy_Buffer(), DEBUG_MODE, delete_protocol_header, FALSE, free_Buffer(), freeNull, gz_decode_file_replace(), HDLIST_CONTENTS_KEY, HTTP_HEADER_CHUNKED, HTTP_HEADER_UNKNOWN_LEN, is_http_header_field(), itostr_ts(), make_Buffer(), PRINT_MESG, recv_https_chunked(), recv_https_closed(), recv_https_content(), recv_https_header(), RECVBUFSZ, search_protocol_header(), TRUE, and Buffer::vldsz.

Referenced by save_https_xml().

00633 {
00634     int    cc=0, hs, len;
00635     Buffer buf, cnt;
00636     FILE*  fp = NULL;
00637     const char tmpd[] = "/tmp";
00638     int   connect;
00639 
00640     if (hdonly!=NULL) *hdonly = FALSE;
00641 
00642     // ヘッダの受信
00643     hs = recv_https_header(sofd, ssl, pl, &len, tsecond, NULL, &connect);
00644     if (state!=NULL) *state = connect;
00645     if (hs<=0) return hs;                                           // エラー
00646     if (len==0 || len==HTTP_HEADER_UNKNOWN_LEN) {                   // ヘッダのみ
00647         if (hdonly!=NULL) *hdonly = TRUE;
00648         return hs;
00649     }
00650 
00651     //PRINT_MESG("++ RECV HEADER ++++++++++\n");
00652     //print_tList(stderr, *pl);
00653     //PRINT_MESG("+++++++++++++++++++++++++\n");
00654 
00655     // ヘッダ中に紛れ込んだコンテンツの取り出し
00656     buf = make_Buffer(RECVBUFSZ);
00657     cnt = search_protocol_header(*pl, (char*)HDLIST_CONTENTS_KEY, 1);
00658     if (cnt.buf!=NULL) {
00659         /*DEBUG_MODE {
00660             if (len==HTTP_HEADER_CHUNKED) {
00661                 char* line = get_line((char*)cnt.buf, 1);
00662                 int chnksz = hexstr2i(line);
00663                 PRINT_MESG("RECV_HTTPS_FILE: INFO: Chunk Size in Header = %d\n", chnksz);
00664                 freeNull(line);
00665             }
00666         }*/
00667         cc = cnt.vldsz;
00668         hs = hs - cc;
00669         copy_Buffer(&cnt, &buf);
00670         free_Buffer(&cnt);
00671     }
00672 
00673     // コンテンツの受信
00674     if (connect) {
00675         if (len>0) {
00676             cc = recv_https_content(sofd, ssl, &buf, len, tsecond, NULL, &connect);
00677         }
00678         else if (len==HTTP_HEADER_CHUNKED) {
00679             cc = recv_https_chunked(sofd, ssl, &buf, tsecond, NULL, &connect);
00680             //PRINT_MESG("+++++++++ RECVSZ = %d\n", buf.vldsz);
00681         }
00682         else { //if (len==HTTP_HEADER_CLOSED_SESSION) {
00683             cc = recv_https_closed(sofd, ssl, &buf, tsecond, NULL);
00684             connect = FALSE;
00685         }
00686     }
00687 
00688     if (cc>0) {
00689         // コンテンツをファイルへ保存
00690         if (fname!=NULL) fp = fopen(fname, "wb");
00691         if (fp!=NULL) {
00692             fwrite(buf.buf, buf.vldsz, 1, fp);
00693             fclose(fp);
00694         }
00695         free_Buffer(&buf);
00696 
00697         //
00698         if (fname!=NULL) {
00699             buf = search_protocol_header(*pl, (char*)"Content-Encoding", 1);
00700 
00701             // Encoding 処理
00702             if (buf.buf!=NULL) {
00703                 // gzip or deflate
00704                 if (!strncasecmp((const char*)buf.buf, "gzip",    4) ||
00705                     !strncasecmp((const char*)buf.buf, "deflate", 7)) {
00706                     #ifdef DISABLE_ZLIB
00707                         DEBUG_MODE PRINT_MESG("RECV_HTTPS_FILE: WARNING: Content-Encoding is [%s]. But zlib is not installed!!\n", buf.buf);
00708                     #else
00709                         if (wdir==NULL) wdir = tmpd;
00710                         cc = gz_decode_file_replace(fname, wdir);
00711                         delete_protocol_header(pl, (char*)"Content-Encoding",  0);
00712 
00713                         // for chunked
00714                         if (is_http_header_field(*pl, (char*)"Transfer-Encoding", (char*)"chunked", 1)) {
00715                             delete_protocol_header(pl, (char*)"Transfer-Encoding", 0);  
00716                             char* str = itostr_ts(cc);
00717                             add_protocol_header(*pl, (char*)"Content-Length", str);  
00718                             freeNull(str);
00719                         }
00720                     #endif
00721                 }
00722 
00723                 else { 
00724                     DEBUG_MODE PRINT_MESG("RECV_HTTPS_FILE: WARNING: unknown Content-Encoding [%s]\n", buf.buf);
00725                 }
00726                 free_Buffer(&buf);
00727             }
00728             
00729             // No Encofing
00730             else {
00731                 // for chunked
00732                 if (is_http_header_field(*pl, (char*)"Transfer-Encoding", (char*)"chunked", 1)) {
00733                     delete_protocol_header(pl, (char*)"Transfer-Encoding", 0);  
00734                     char* str = itostr_ts(cc);
00735                     add_protocol_header(*pl, (char*)"Content-Length", str);  
00736                     freeNull(str);
00737                 }
00738             }
00739         }
00740         cc = cc + hs;
00741     }
00742 
00743     if (state!=NULL) *state = connect;
00744     return cc;
00745 }

Here is the call graph for this function:

Here is the caller graph for this function:

int recv_https_header ( int  sofd,
SSL *  ssl,
tList **  pl,
int *  len,
int  tm,
FILE *  fp,
int *  state 
)

int recv_https_header(int sofd, SSL* ssl, tList** pl, int* len, int tm, FILE* fp, int* state)

HTTPS通信のヘッダ部分を受信して,リストに格納する.
NULLでない fp が指定された場合,受信した全てのデータをファイルに保存する. 受信したデータが HTTPSでない場合は,*pl の HDLIST_CONTENTS_KEY の値として受信データを格納する.

Parameters:
sofd 接続相手へのソケット
ssl 接続相手への SSLソケット.SSL通信でない場合は NULLを指定.
[out] *pl ヘッダ情報が格納されるリストへのポインタ.NULLなら格納いない. (*pl)->ldat.id に HTTPデータのコマンド種別が入る.(HTTP_GET_METHOD など)
[out] len ヘッダ中の "Content-Length" の値(正の値). "Content-Length" が存在しなければ HTTP_HEADER_UNKNOWN_LEN (0未満). チャンク形式なら HTTP_HEADER_CHUNKED (0未満). 引き続く1回のセッション内でボディを転送するのなら,HTTP_HEADER_CLOSED_SESSION (0未満). 受信データが HTTP でないなら HTTP_HEADER_NOT_HTTP (0未満).
fp 受信した全てのデータを保存するためのファイルポインタ.NULLの場合は保存しない.
[out] state サーバとの接続状態.接続中なら TRUE.切断した場合は FALSE.NULLを指定しても良い.
Return values:
0以上 受信した全バイト数
0 正常切断
JBXL_SSL_RECV_ERROR 受信エラー
JBXL_ARGS_ERROR 無効な sofdを指定した または len にNULL を指定した

Definition at line 196 of file https_tool.c.

References add_tList_node_Buffer, Buffer::buf, FALSE, find_tList_top(), free_Buffer(), get_http_method(), get_http_status_num(), get_http_version_num(), get_protocol_header_list_seq(), HDLIST_CONTENTS_KEY, HDLIST_END_KEY, HTTP_GET_METHOD, HTTP_HEADER_CHUNKED, HTTP_HEADER_CLOSED_SESSION, HTTP_HEADER_NOT_HTTP, HTTP_HEADER_UNKNOWN_LEN, HTTP_UNKNOWN_METHOD, is_http_header_field(), JBXL_ARGS_ERROR, JBXL_SSL_RECV_ERROR, Loop, make_Buffer(), make_Buffer_str, RECVBUFSZ, search_protocol_header(), ssl_tcp_recv_Buffer_wait(), strncasecmp_tList(), TRUE, and Buffer::vldsz.

Referenced by recv_https_Buffer(), and recv_https_file().

00197 {
00198     int  cc, sz, com;
00199     Buffer mbuf;
00200     tList* lp;
00201     int  connect = TRUE;
00202 
00203     if (sofd<=0)   return JBXL_ARGS_ERROR;
00204     if (len==NULL) return JBXL_ARGS_ERROR;
00205     *len = HTTP_HEADER_UNKNOWN_LEN;
00206 
00207     mbuf = make_Buffer(RECVBUFSZ);
00208 
00209     sz  = 0;
00210     lp  = NULL;
00211     *pl = NULL;
00212 
00213     cc  = ssl_tcp_recv_Buffer_wait(sofd, ssl, &mbuf, tm);
00214     com = get_http_method((char*)mbuf.buf);
00215 
00216     if (com>HTTP_UNKNOWN_METHOD) {
00217         Loop {
00218             if (cc>0) {
00219                 if (fp!=NULL) fwrite(mbuf.buf, cc, 1, fp);
00220                 lp = get_protocol_header_list_seq(lp, mbuf, ':', TRUE, TRUE);
00221                 sz += cc;
00222                 /*
00223                 if (sz==cc) {       // is HTTPS?
00224                     tList* ll = find_tList_top(lp);
00225                     if (get_http_header_method(ll)==HTTP_UNKNOWN_METHOD) {
00226                         connect = HTTP_HEADER_NOT_HTTP;
00227                         *pl = ll;
00228                         break;
00229                     }
00230                 }*/
00231             }
00232             else {
00233                 connect = FALSE;
00234                 break;
00235             }
00236 
00237             *pl = find_tList_top(lp);
00238             if (strncasecmp_tList(*pl, (char*)HDLIST_END_KEY, 0, 1)!=NULL) break;
00239             //
00240             cc = ssl_tcp_recv_Buffer_wait(sofd, ssl, &mbuf, tm);
00241         }
00242     }
00243     else {
00244         if (mbuf.vldsz>0) {
00245             Buffer key = make_Buffer_str(HDLIST_CONTENTS_KEY);
00246             *pl = add_tList_node_Buffer(NULL, key, mbuf);
00247             free_Buffer(&key);
00248         }
00249         *len = HTTP_HEADER_NOT_HTTP;
00250         connect = FALSE;
00251     }
00252 
00253     free_Buffer(&mbuf);
00254     if (*pl!=NULL) (*pl)->ldat.id = com;
00255     if (state!=NULL) *state = connect;
00256     //
00257     if (sz==0 && cc==0) return 0;      // 正常切断
00258     if (sz==0 && cc<0)  return JBXL_SSL_RECV_ERROR;
00259     if (*pl==NULL)      return JBXL_SSL_RECV_ERROR;
00260     if (*len==HTTP_HEADER_NOT_HTTP) return cc;
00261 
00262     // コンテンツの長さを得る.
00263     /*
00264     Buffer hbuf = search_protocol_header(*pl, (char*)HDLIST_FIRST_LINE_KEY, 1);
00265     if (hbuf.buf!=NULL) {
00266         if (!strncasecmp((char*)hbuf.buf, "GET ", 4)) {
00267             *len = 0;
00268         }
00269         free_Buffer(&hbuf);
00270     }*/
00271 
00272     if (com==HTTP_GET_METHOD) *len = 0;
00273 
00274     if (*len==HTTP_HEADER_UNKNOWN_LEN) {
00275         if (is_http_header_field(*pl, (char*)"Transfer-Encoding", (char*)"chunked", 1)) {
00276             *len = HTTP_HEADER_CHUNKED;
00277         }
00278     }
00279 
00280     if (*len==HTTP_HEADER_UNKNOWN_LEN) {
00281         Buffer hbuf = search_protocol_header(*pl, (char*)"Content-Length", 1);
00282         if (hbuf.buf!=NULL) {
00283             *len = atoi((const char*)hbuf.buf);
00284             free_Buffer(&hbuf);
00285         }
00286     }
00287 
00288     if (*len==HTTP_HEADER_UNKNOWN_LEN) {
00289         if (get_http_version_num(*pl)<=1.0 && get_http_status_num(*pl)>=200) {
00290             if (is_http_header_field(*pl, (char*)"Connection", (char*)"close", 1)) {
00291                 *len = HTTP_HEADER_CLOSED_SESSION;
00292             }
00293         }
00294     }
00295 
00296     return sz;
00297 }

Here is the call graph for this function:

Here is the caller graph for this function:

int save_https_xml ( int  cofd,
SSL *  ssl,
tList **  pl,
tXML **  xml,
char **  recvfn,
const char *  wdir,
int  timeout,
int *  state 
)

int save_https_xml(int cofd, SSL* ssl, tList** pl, tXML** xml, char** recvfn, const char* wdir, int timeout, int* state)

受信した XML通信データをファイルに保存

Parameters:
cofd 接続相手へのソケット
ssl 接続相手への SSLソケット.SSL通信でない場合は NULL を指定.
[out] *pl 受信したヘッダが格納されるリストへのポインタ.
[out] *xml パースされたデータが格納されるXML構造体へのポインタ
[out] *recvfn 保存するファイル名
wdir 作業用ディレクトリを指定する.NULLの場合は /tmp になる.
timeout 最初の受信までのタイムアウト(s)
[out] state サーバとの接続状態.接続中なら TRUE.切断した場合は FALSE.NULLを指定しても良い.
Return values:
1以上 受信したファイルのサイズ(Byte)(ヘッダを含む)
0 正常切断
JBXL_SSL_RECV_ERROR 受信エラー
JBXL_NET_RECV_TIMEOUT タイムアウトした.

Definition at line 768 of file https_tool.c.

References del_xml, free_Buffer(), JBXL_SSL_RECV_ERROR, recv_https_file(), search_protocol_header(), temp_filename(), WORK_FILENAME_LEN, and xml_parse_file().

00769 {
00770     int header;
00771 
00772     if (pl==NULL || recvfn==NULL) return 0;
00773 
00774     *pl = NULL;
00775     if (xml!=NULL) *xml = NULL;
00776     *recvfn = temp_filename(wdir, WORK_FILENAME_LEN);
00777    
00778     int cc = recv_https_file(cofd, ssl, pl, *recvfn, wdir, timeout, &header, state);
00779     if (cc<=0 || *pl==NULL) {
00780         free(*recvfn);
00781         *recvfn = NULL;
00782         if (cc==0) return 0;
00783         return JBXL_SSL_RECV_ERROR;
00784     }
00785 
00786     if (header) {
00787         free(*recvfn);
00788         *recvfn = NULL;
00789     }
00790     else {
00791 
00792         if (xml!=NULL && *pl!=NULL && *recvfn!=NULL && cc>0) {
00793             Buffer buf = search_protocol_header(*pl, (char*)"Content-Type", 1);
00794             *xml = xml_parse_file(*recvfn);
00795             if (*xml!=NULL && (*xml)->state<0) del_xml(xml);
00796             free_Buffer(&buf);
00797         }
00798     }
00799 
00800     return  cc;
00801 }

Here is the call graph for this function:

int send_https_Buffer ( int  sofd,
SSL *  ssl,
tList pl,
Buffer buf 
)

int send_https_Buffer(int sofd, SSL* ssl, tList* pl, Buffer* buf)

ヘッダとバッファの内容を HTTP通信で送信する.

Parameters:
sofd 接続相手へのソケット
ssl 接続相手への SSLソケット.SSL通信でない場合は NULL を指定.
pl ファイルに先立って送信されるヘッダが格納されるリストへのポインタ.
buf 送信するコンテンツが格納された Buffer変数へのポインタ.
Return values:
0以上 送信したデータの全サイズ(Byte)
JBXL_ARGS_ERROR リストへのポインタが NULL

Definition at line 68 of file https_tool.c.

References free_Buffer(), rebuild_http_Buffer(), and ssl_tcp_send_Buffer().

00069 {
00070     int sz;
00071     Buffer snd;
00072 
00073  /*
00074     int nobody = FALSE;
00075 
00076     if (pl==NULL) return JBXL_ARGS_ERROR;
00077     if (buf==NULL || buf->vldsz<0 || buf->buf==NULL) nobody = TRUE;
00078 
00079     if (!nobody) {
00080         // Content-Length の書き換え
00081         tList* pp = pl;
00082         while(pp!=NULL) {
00083             if (!strcasecmp((const char*)(pp->ldat.key.buf), "Content-Length")) {
00084                 copy_i2Buffer(buf->vldsz, &(pp->ldat.val));
00085                 break;
00086             }
00087             pp = pp->next;
00088         }
00089     }
00090 
00091     snd = restore_protocol_header(pl, (char*)": ", OFF, NULL);
00092     if (!nobody) cat_Buffer(buf, &snd);
00093 */
00094 
00095     snd = rebuild_http_Buffer(pl, buf);
00096     sz  = ssl_tcp_send_Buffer(sofd, ssl, &snd);
00097     free_Buffer(&snd);
00098 
00099     return sz;
00100 }

Here is the call graph for this function:

int send_https_file ( int  sofd,
SSL *  ssl,
tList pl,
const char *  fname 
)

int send_https_file(int sofd, SSL* ssl, tList* pl, const char* fname)

ヘッダとファイルの内容を HTTPS通信で送信する.

Parameters:
sofd 接続相手へのソケット
ssl 接続相手への SSLソケット.SSL通信でない場合は NULL を指定.
pl ファイルに先立って送信されるヘッダが格納されるリストへのポインタ.
fname 送信するファイル名.ヘッダのみ送る場合は NULL
Return values:
0以上 送信したデータの全サイズ(Byte)
JBXL_ARGS_ERROR リストへのポインタが NULL
JBXL_MALLOC_ERROR メモリ確保エラー

Definition at line 118 of file https_tool.c.

References cat_b2Buffer(), copy_s2Buffer, file_size(), free_Buffer(), JBXL_ARGS_ERROR, JBXL_MALLOC_ERROR, OFF, restore_protocol_header(), ssl_tcp_send_Buffer(), and UNUSED.

00119 {
00120     int   sz = 0;
00121     FILE* fp = NULL;
00122     char num[20];
00123     tList* pp;
00124     unsigned char* html;
00125     Buffer  buf;
00126 
00127     size_t rs;
00128     UNUSED(rs);
00129 
00130     if (pl==NULL) return JBXL_ARGS_ERROR;
00131     if (fname!=NULL) sz = file_size((char*)fname);
00132     if (sz<=0) sz = 0;
00133     snprintf(num, 18, "%d", sz);
00134 
00135     // Content-Length の書き換え
00136     pp = pl;
00137     while(pp!=NULL) {
00138         if (!strcasecmp((const char*)(pp->ldat.key.buf), "Content-Length")) {
00139             copy_s2Buffer(num, &(pp->ldat.val));
00140             break;
00141         }
00142         pp = pp->next;
00143     }
00144 
00145     buf = restore_protocol_header(pl, (char*)": ", OFF, NULL);
00146 
00147     if (fname!=NULL && sz!=0) fp = fopen(fname, "rb");
00148     if (fp!=NULL) {
00149         html = (unsigned char*)malloc(sz+1);
00150         if (html==NULL) {
00151             fclose(fp);
00152             free_Buffer(&buf);
00153             return JBXL_MALLOC_ERROR;
00154         }
00155 
00156         memset(html, 0, sz+1);
00157         rs = fread(html, sz, 1, fp); 
00158         fclose(fp);
00159 
00160         cat_b2Buffer(html, &buf, sz);
00161         free(html);
00162     }
00163 
00164     sz = ssl_tcp_send_Buffer(sofd, ssl, &buf);
00165     free_Buffer(&buf);
00166 
00167     return sz;
00168 }

Here is the call graph for this function:

int send_https_header ( int  sofd,
SSL *  ssl,
tList pp,
int  mode 
)

int send_https_header(int sofd, SSL* ssl, tList* pp, int mode)

ヘッダリストの内容を HTTPS通信で送信する. ヘッダ中の Content-Length の値は操作しない.

Parameters:
sofd 接続相手へのソケット
ssl 接続相手への SSLソケット.SSL通信でない場合は NULL を指定.
pp 送信するヘッダが格納されるリストへのポインタ.
mode ON: ヘッダリスト内にコンテンツの一部があればそれも送信する.
mode OFF: ヘッダリスト内にコンテンツの一部があっても送信しない.
Return values:
0以上 mode==OFF: 送信した全データバイト数. mode==ON : 送信したコンテンツのバイト数.
0未満 エラー
JBXL_ARGS_ERROR リストへのポインタが NULL

Definition at line 36 of file https_tool.c.

References free_Buffer(), JBXL_ARGS_ERROR, ON, restore_protocol_header(), ssl_tcp_send_Buffer(), and Buffer::vldsz.

00037 {
00038     int    hs=0, sz=0;
00039     Buffer buf;
00040 
00041     if (pp==NULL) return JBXL_ARGS_ERROR;
00042 
00043     buf = restore_protocol_header(pp, (char*)": ", mode, &hs);
00044     if (buf.vldsz>0) {
00045         sz  = ssl_tcp_send_Buffer(sofd, ssl, &buf);
00046         if (mode==ON) sz = sz - hs;
00047     }
00048 
00049     free_Buffer(&buf);
00050     return sz;
00051 }

Here is the call graph for this function:


Generated on 15 Nov 2023 for JunkBox_Lib by  doxygen 1.6.1