HTTP ツールライブラリ ヘッダ. More...
#include "txml.h"
#include "protocol.h"
#include "gz_tool.h"
Go to the source code of this file.
Defines | |
#define | HTTP_CONNECTION_CLOSE 0 |
#define | HTTP_CONNECTION_KEEP 1 |
#define | HTTP_HEADER_NOT_HTTP -1990 |
#define | HTTP_HEADER_CLOSED_SESSION -1997 |
#define | HTTP_HEADER_CHUNKED -1998 |
#define | HTTP_HEADER_UNKNOWN_LEN -1999 |
#define | HTTP_ERROR_METHOD -1 |
HTTP で無い場合は負数にする.. | |
#define | HTTP_UNKNOWN_METHOD 0 |
0 固定.これ以下はエラーとする. | |
#define | HTTP_GET_METHOD 1 |
#define | HTTP_PUT_METHOD 2 |
#define | HTTP_POST_METHOD 3 |
#define | HTTP_DELETE_METHOD 4 |
#define | HTTP_OPTIONS_METHOD 5 |
#define | HTTP_HEAD_METHOD 6 |
#define | HTTP_TRACE_METHOD 7 |
#define | HTTP_CONNECT_METHOD 8 |
#define | HTTP_PATCH_METHOD 9 |
#define | HTTP_LINK_METHOD 10 |
#define | HTTP_UNLINK_METHOD 11 |
#define | HTTP_PROPFIND_METHOD 20 |
#define | HTTP_PROPPATCH_METHOD 21 |
#define | HTTP_MKCOL_METHOD 22 |
#define | HTTP_COPY_METHOD 23 |
#define | HTTP_MOVE_METHOD 24 |
#define | HTTP_LOCK_METHOD 25 |
#define | HTTP_UNLOCK_METHOD 26 |
#define | HTTP_RESPONSE_METHOD 99 |
#define | HTTP_TIMEOUT 60 |
秒 | |
#define | HTTP_RESPONSE_TIMEOUT 180 |
秒 | |
#define | HTTP_PROXY_TIMEOUT 60 |
秒 | |
Functions | |
int | recv_http_header (int sock, tList **pl, int *len, int tm, FILE *fp, int *state) |
int | send_http_header (int sock, tList *pl, int mode) |
int | recv_http_content (int sofd, Buffer *buf, int len, int tm, FILE *fp, int *state) |
int | recv_http_chunked (int sofd, Buffer *buf, int tm, FILE *fp, int *state) |
int | recv_http_closed (int sofd, Buffer *buf, int tm, FILE *fp) |
int | recv_http_chunked_remain (int sofd, Buffer *buf, int chnksz, int tm) |
int | recv_http_Buffer (int sock, tList **pl, Buffer *buf, int timeout, int *hdonly, int *state, int nochunk) |
int | send_http_Buffer (int sock, tList *pl, Buffer *buf) |
int | recv_http_file (int sock, tList **pl, const char *fn, const char *wdir, int timeout, int *hdonly, int *state) |
int | send_http_file (int sock, tList *pl, const char *fn) |
int | save_http_xml (int sock, tList **pl, tXML **xml, char **recvfn, const char *wdir, int timeout, int *state) |
int | get_http_method (char *data) |
int | is_http_header_field (tList *pl, char *field, char *value, int n) |
int | get_http_header_method (tList *pl) |
void | set_http_host_header (tList *pl, char *hname, unsigned short hport) |
void | dump_http_header (FILE *fp, tList *pp) |
int | get_http_status_num (tList *pl) |
float | get_http_version_num (tList *pl) |
int | get_chunked_size (char *ptr, int *hdsz, int *tlsz) |
char * | get_http_header_date (time_t tm) |
Buffer | rebuild_http_Buffer (tList *pl, Buffer *buf) |
void | simple_web_proxy (int bofd, char *myip, int tmout) |
int | www2browser_relay (int bofd, int wofd, int btm, int wtm, int keep) |
Buffer | http_proxy_header_analyze (tList *pl, Buffer *server, unsigned short *sport, int *timeout, int *keep) |
int | tcp_relay (int sofd, int cofd, int tm) |
int | send_http_res_file (int sock, char *fn, int mode) |
void | send_http_passwd_req (int sock) |
Definition in file http_tool.h.
#define HTTP_CONNECT_METHOD 8 |
Definition at line 44 of file http_tool.h.
Referenced by get_http_method().
#define HTTP_CONNECTION_CLOSE 0 |
Definition at line 25 of file http_tool.h.
Referenced by send_http_res_file().
#define HTTP_CONNECTION_KEEP 1 |
Definition at line 26 of file http_tool.h.
#define HTTP_COPY_METHOD 23 |
Definition at line 53 of file http_tool.h.
Referenced by get_http_method().
#define HTTP_DELETE_METHOD 4 |
Definition at line 40 of file http_tool.h.
Referenced by get_http_method().
#define HTTP_ERROR_METHOD -1 |
Definition at line 33 of file http_tool.h.
#define HTTP_GET_METHOD 1 |
Definition at line 37 of file http_tool.h.
Referenced by get_http_method(), recv_http_header(), and recv_https_header().
#define HTTP_HEAD_METHOD 6 |
Definition at line 42 of file http_tool.h.
Referenced by get_http_method().
#define HTTP_HEADER_CHUNKED -1998 |
Definition at line 29 of file http_tool.h.
Referenced by recv_http_Buffer(), recv_http_file(), recv_http_header(), recv_https_Buffer(), recv_https_file(), recv_https_header(), and www2browser_relay().
#define HTTP_HEADER_CLOSED_SESSION -1997 |
Definition at line 28 of file http_tool.h.
Referenced by recv_http_header(), recv_https_header(), and www2browser_relay().
#define HTTP_HEADER_NOT_HTTP -1990 |
Definition at line 27 of file http_tool.h.
Referenced by recv_http_header(), and recv_https_header().
#define HTTP_HEADER_UNKNOWN_LEN -1999 |
Definition at line 30 of file http_tool.h.
Referenced by recv_http_Buffer(), recv_http_file(), recv_http_header(), recv_https_Buffer(), recv_https_file(), and recv_https_header().
#define HTTP_LINK_METHOD 10 |
Definition at line 46 of file http_tool.h.
Referenced by get_http_method().
#define HTTP_LOCK_METHOD 25 |
Definition at line 55 of file http_tool.h.
Referenced by get_http_method().
#define HTTP_MKCOL_METHOD 22 |
Definition at line 52 of file http_tool.h.
Referenced by get_http_method().
#define HTTP_MOVE_METHOD 24 |
Definition at line 54 of file http_tool.h.
Referenced by get_http_method().
#define HTTP_OPTIONS_METHOD 5 |
Definition at line 41 of file http_tool.h.
Referenced by get_http_method().
#define HTTP_PATCH_METHOD 9 |
Definition at line 45 of file http_tool.h.
Referenced by get_http_method().
#define HTTP_POST_METHOD 3 |
Definition at line 39 of file http_tool.h.
Referenced by get_http_method().
#define HTTP_PROPFIND_METHOD 20 |
Definition at line 50 of file http_tool.h.
Referenced by get_http_method().
#define HTTP_PROPPATCH_METHOD 21 |
Definition at line 51 of file http_tool.h.
Referenced by get_http_method().
#define HTTP_PROXY_TIMEOUT 60 |
Definition at line 62 of file http_tool.h.
Referenced by simple_web_proxy().
#define HTTP_PUT_METHOD 2 |
Definition at line 38 of file http_tool.h.
Referenced by get_http_method().
#define HTTP_RESPONSE_METHOD 99 |
Definition at line 58 of file http_tool.h.
Referenced by get_http_method().
#define HTTP_RESPONSE_TIMEOUT 180 |
Definition at line 61 of file http_tool.h.
#define HTTP_TIMEOUT 60 |
Definition at line 60 of file http_tool.h.
#define HTTP_TRACE_METHOD 7 |
Definition at line 43 of file http_tool.h.
Referenced by get_http_method().
#define HTTP_UNKNOWN_METHOD 0 |
Definition at line 34 of file http_tool.h.
Referenced by get_http_header_method(), get_http_method(), recv_http_Buffer(), recv_http_header(), recv_https_Buffer(), and recv_https_header().
#define HTTP_UNLINK_METHOD 11 |
Definition at line 47 of file http_tool.h.
Referenced by get_http_method().
#define HTTP_UNLOCK_METHOD 26 |
Definition at line 56 of file http_tool.h.
Referenced by get_http_method().
void dump_http_header | ( | FILE * | fp, | |
tList * | pp | |||
) |
void dump_http_header(FILE* fp, tList* pp)
HTTPのヘッダ(pp)の内容をダンプする.
Definition at line 959 of file http_tool.c.
References FALSE, fdump(), HDLIST_CONTENTS_KEY, and TRUE.
00960 { 00961 if (fp==NULL) fp = stderr; 00962 00963 if (pp!=NULL) { 00964 int image = FALSE; 00965 while(pp!=NULL) { 00966 tList_data ld = pp->ldat; 00967 if (!strcasecmp((const char*)ld.key.buf, "Content-Type")) { 00968 if (!strncasecmp((const char*)ld.val.buf, "image", 5)) image = TRUE; 00969 //else if (!strncasecmp((unsigned char*)ld.val.buf, "xxxx", 5)) image = TRUE; 00970 } 00971 00972 if (!strcasecmp((const char*)ld.key.buf, HDLIST_CONTENTS_KEY) && image==TRUE) { 00973 fprintf(fp, "[%d] [%d] [%s] [%d]\n", ld.id, ld.lv, ld.key.buf, ld.val.vldsz); 00974 fdump(fp, (unsigned char*)ld.val.buf, ld.val.vldsz); 00975 } 00976 else { 00977 fprintf(fp, "[%d] [%d] [%s] [%s]\n", ld.id, ld.lv, ld.key.buf, ld.val.buf); 00978 } 00979 pp = pp->next; 00980 } 00981 } 00982 else { 00983 fprintf(fp, "(List is NULL)\n"); 00984 } 00985 return; 00986 }
int get_chunked_size | ( | char * | ptr, | |
int * | hdsz, | |||
int * | tlsz | |||
) |
int get_chunked_size(char* ptr, int* hdsz, int* tlsz)
データの先頭のチャンクのサイズを得る. hdsz にChunkで使用されるデータのヘッダのサイズが入る. tlsz にChunkで使用されるデータのトレーラのサイズが入る.
hdsz + ck + *tlsz が全データサイズ
Definition at line 999 of file http_tool.c.
References hexstr2i(), and L_32.
Referenced by recv_http_chunked(), and recv_https_chunked().
01000 { 01001 int ck = 0, hd = 0, tl = 0; 01002 char hex[L_32]; 01003 01004 int i = 0; 01005 while (ptr[i]!=0x0d && i<L_32) { 01006 hex[i] = ptr[i]; 01007 i++; 01008 } 01009 if (i==L_32) { 01010 if (hdsz!=NULL) *hdsz = 0; 01011 if (tlsz!=NULL) *tlsz = 0; 01012 return -1; 01013 } 01014 01015 if (ptr[i+1]==0x0a) hd = i + 2; 01016 else hd = i + 1; 01017 if (hdsz!=NULL) *hdsz = hd; 01018 01019 hex[i] = '\0'; 01020 ck = hexstr2i(hex); 01021 01022 if (ptr[ck+hd]==0x0d) { 01023 tl++; 01024 if (ptr[ck+hd+tl]==0x0a) tl++; 01025 } 01026 if (tlsz!=NULL) *tlsz = tl; 01027 01028 return ck; 01029 }
char* get_http_header_date | ( | time_t | tm | ) |
Definition at line 1034 of file http_tool.c.
References get_gmt_timestamp().
01035 { 01036 char* buf = get_gmt_timestamp(date, "%a, %d %b %Y %H:%M:%S %Z"); 01037 01038 return buf; 01039 }
int get_http_header_method | ( | tList * | pl | ) |
int get_http_header_method(tList* pl)
ヘッダ情報の格納された plから,HTTPコマンドとパスを取り出す.
Definition at line 913 of file http_tool.c.
References Buffer::buf, get_http_method(), HDLIST_FIRST_LINE_KEY, HTTP_UNKNOWN_METHOD, and search_protocol_header().
00914 { 00915 int ret = HTTP_UNKNOWN_METHOD; 00916 00917 if (pl==NULL) return ret; 00918 00919 Buffer hbuf = search_protocol_header(pl, (char*)HDLIST_FIRST_LINE_KEY, 1); 00920 if (hbuf.buf!=NULL) ret = get_http_method((char*)hbuf.buf); 00921 00922 return ret; 00923 }
int get_http_method | ( | char * | data | ) |
Definition at line 850 of file http_tool.c.
References ex_strcmp, HTTP_CONNECT_METHOD, HTTP_COPY_METHOD, HTTP_DELETE_METHOD, HTTP_GET_METHOD, HTTP_HEAD_METHOD, HTTP_LINK_METHOD, HTTP_LOCK_METHOD, HTTP_MKCOL_METHOD, HTTP_MOVE_METHOD, HTTP_OPTIONS_METHOD, HTTP_PATCH_METHOD, HTTP_POST_METHOD, HTTP_PROPFIND_METHOD, HTTP_PROPPATCH_METHOD, HTTP_PUT_METHOD, HTTP_RESPONSE_METHOD, HTTP_TRACE_METHOD, HTTP_UNKNOWN_METHOD, HTTP_UNLINK_METHOD, and HTTP_UNLOCK_METHOD.
Referenced by get_http_header_method(), recv_http_header(), and recv_https_header().
00851 { 00852 if (ex_strcmp("GET ", data)) return HTTP_GET_METHOD; 00853 else if (ex_strcmp("PUT ", data)) return HTTP_PUT_METHOD; 00854 else if (ex_strcmp("POST ", data)) return HTTP_POST_METHOD; 00855 else if (ex_strcmp("DELETE ", data)) return HTTP_DELETE_METHOD; 00856 else if (ex_strcmp("OPTIONS ", data)) return HTTP_OPTIONS_METHOD; 00857 else if (ex_strcmp("HEAD ", data)) return HTTP_HEAD_METHOD; 00858 else if (ex_strcmp("TRACE ", data)) return HTTP_TRACE_METHOD; 00859 else if (ex_strcmp("CONNECT ", data)) return HTTP_CONNECT_METHOD; 00860 else if (ex_strcmp("PATCH ", data)) return HTTP_PATCH_METHOD; 00861 else if (ex_strcmp("LINK ", data)) return HTTP_LINK_METHOD; 00862 else if (ex_strcmp("UNLINK ", data)) return HTTP_UNLINK_METHOD; 00863 else if (ex_strcmp("HTTP/", data)) return HTTP_RESPONSE_METHOD; 00864 // WebDAV 00865 else if (ex_strcmp("PROPFIND ", data)) return HTTP_PROPFIND_METHOD; 00866 else if (ex_strcmp("PROPPATCH ", data)) return HTTP_PROPPATCH_METHOD; 00867 else if (ex_strcmp("MKCOL ", data)) return HTTP_MKCOL_METHOD; 00868 else if (ex_strcmp("COPY ", data)) return HTTP_COPY_METHOD; 00869 else if (ex_strcmp("MOVE ", data)) return HTTP_MOVE_METHOD; 00870 else if (ex_strcmp("LOCK ", data)) return HTTP_LOCK_METHOD; 00871 else if (ex_strcmp("UNLOCK ", data)) return HTTP_UNLOCK_METHOD; 00872 00873 return HTTP_UNKNOWN_METHOD; 00874 }
int get_http_status_num | ( | tList * | pl | ) |
Definition at line 1425 of file http_tool.c.
References Buffer::buf, cawk_Buffer(), free_Buffer(), HDLIST_FIRST_LINE_KEY, and search_protocol_header().
Referenced by recv_http_header(), and recv_https_header().
01426 { 01427 int pnum = 0; 01428 01429 Buffer dat = search_protocol_header(pl, (char*)HDLIST_FIRST_LINE_KEY, 1); 01430 if (dat.buf!=NULL) { 01431 if (!strncasecmp((const char*)dat.buf, "HTTP/", 5)) { 01432 Buffer num = cawk_Buffer(dat, ' ', 2); 01433 if (num.buf!=NULL) { 01434 pnum = atoi((const char*)num.buf); 01435 free_Buffer(&num); 01436 } 01437 } 01438 free_Buffer(&dat); 01439 } 01440 01441 return pnum; 01442 }
float get_http_version_num | ( | tList * | pl | ) |
Definition at line 1446 of file http_tool.c.
References Buffer::buf, cawk_Buffer(), free_Buffer(), HDLIST_FIRST_LINE_KEY, and search_protocol_header().
Referenced by recv_http_header(), and recv_https_header().
01447 { 01448 float ver = 0.0; 01449 01450 Buffer dat = search_protocol_header(pl, (char*)HDLIST_FIRST_LINE_KEY, 1); 01451 if (dat.buf!=NULL) { 01452 if (!strncasecmp((const char*)dat.buf, "HTTP/", 5)) { 01453 Buffer num = cawk_Buffer(dat, ' ', 1); 01454 if (num.buf!=NULL) { 01455 ver = (float)atof((char*)&num.buf[5]); 01456 free_Buffer(&num); 01457 } 01458 } 01459 else { 01460 Buffer buf = cawk_Buffer(dat, ' ', 3); 01461 if (!strncasecmp((const char*)buf.buf, "HTTP/", 5)) { 01462 Buffer num = cawk_Buffer(buf, ' ', 1); 01463 if (num.buf!=NULL) { 01464 ver = (float)atof((char*)&num.buf[5]); 01465 free_Buffer(&num); 01466 } 01467 } 01468 free_Buffer(&buf); 01469 } 01470 free_Buffer(&dat); 01471 } 01472 01473 return ver; 01474 }
Buffer http_proxy_header_analyze | ( | tList * | pl, | |
Buffer * | server, | |||
unsigned short * | sport, | |||
int * | timeout, | |||
int * | keep | |||
) |
Buffer http_proxy_header_analyze(tList* pl, Buffer* server, unsigned short* sport, int* timeout, int* keep)
ブラウザからのプロキシ用リクエストを解析する.
pl | 解析するヘッダ情報の入ったリストへのポインタ | |
[out] | server | 接続相手の名前またはIPアドレスが代入される |
[out] | sport | 接続相手のポート番号が代入される. |
[out] | timeout | ブラウザからの Keep-Alive の値が代入される. |
[out] | keep | 接続を維持するかどうかが代入される.(TRUE:維持する/FALSE:維持しない) |
Definition at line 1185 of file http_tool.c.
References Buffer::buf, cat_Buffer(), cat_s2Buffer, cawk_Buffer(), copy_Buffer(), decomp_url(), del_tList_node(), FALSE, free_Buffer(), HDLIST_FIRST_LINE_KEY, init_Buffer(), strncasecmp_tList(), and TRUE.
Referenced by simple_web_proxy().
01186 { 01187 tList* frst; 01188 tList* lst; 01189 Buffer cmnd, url, ptcl; 01190 Buffer srvdir, bufport; 01191 01192 cmnd = init_Buffer(); 01193 srvdir = init_Buffer(); 01194 *server = init_Buffer(); 01195 *sport = 0; 01196 *timeout = 0; 01197 *keep = FALSE; 01198 01199 frst = strncasecmp_tList(pl, (char*)HDLIST_FIRST_LINE_KEY, 0, 1); 01200 if (frst!=NULL) { 01201 cmnd = cawk_Buffer(frst->ldat.val, ' ', 1); 01202 url = cawk_Buffer(frst->ldat.val, ' ', 2); 01203 ptcl = cawk_Buffer(frst->ldat.val, ' ', 3); 01204 decomp_url(url, NULL, NULL, server, sport, &srvdir); 01205 } 01206 else return cmnd; 01207 01208 if (server->buf==NULL) { 01209 lst = strncasecmp_tList(pl, (char*)"Host", 0, 1); 01210 if (lst!=NULL) { 01211 *server = cawk_Buffer(lst->ldat.val, ':', 1); 01212 bufport = cawk_Buffer(lst->ldat.val, ':', 2); 01213 if (bufport.buf!=NULL) *sport = atoi((char*)bufport.buf); 01214 free_Buffer(&bufport); 01215 } 01216 } 01217 if (*sport==0) *sport = 80; 01218 01219 lst = strncasecmp_tList(pl, (char*)"Keep-Alive", 0, 1); 01220 if (lst!=NULL) { 01221 if (lst->ldat.val.buf!=NULL) *timeout = atoi((char*)(lst->ldat.val.buf)); 01222 del_tList_node(&lst); 01223 } 01224 01225 lst = strncasecmp_tList(pl, (char*)"Proxy-Connection", 0, 1); 01226 if (lst!=NULL) { 01227 if (!strcasecmp((char*)(lst->ldat.val.buf), "keep-alive")) *keep = TRUE; 01228 del_tList_node(&lst); 01229 } 01230 01231 free_Buffer(&(frst->ldat.val)); 01232 copy_Buffer (&cmnd, &(frst->ldat.val)); 01233 cat_s2Buffer(" ", &(frst->ldat.val)); 01234 cat_Buffer (&srvdir, &(frst->ldat.val)); 01235 cat_s2Buffer(" ", &(frst->ldat.val)); 01236 cat_Buffer (&ptcl, &(frst->ldat.val)); 01237 01238 free_Buffer(&url); 01239 free_Buffer(&ptcl); 01240 free_Buffer(&srvdir); 01241 01242 return cmnd; 01243 }
int is_http_header_field | ( | tList * | pl, | |
char * | field, | |||
char * | value, | |||
int | n | |||
) |
int is_http_header_field(tList* pl, char* field, char* value, int n)
HTTPのヘッダ部分で n番目の filed の値が valueなら TRUEを返し,違っていれば FALSEを返す.
pl | ヘッダ情報が格納されるリストへのポインタ | |
field | ヘッダ中の フィールド名. | |
value | 比較するフィールドの値. | |
n | フィールドが複数あった場合は n番目のフィールドと比較する |
TRUE | フィールドの値が一致した. | |
FALSE | フィールドの値が一致しなかった. |
Definition at line 891 of file http_tool.c.
References Buffer::buf, FALSE, free_Buffer(), search_protocol_header(), and TRUE.
Referenced by recv_http_Buffer(), recv_http_file(), recv_http_header(), recv_https_Buffer(), recv_https_file(), and recv_https_header().
00892 { 00893 int ret = FALSE; 00894 00895 Buffer hbuf = search_protocol_header(pl, field, n); 00896 if (hbuf.buf!=NULL) { 00897 if (!strcasecmp((char*)hbuf.buf, value)) { 00898 ret = TRUE; 00899 } 00900 free_Buffer(&hbuf); 00901 } 00902 00903 return ret; 00904 }
Definition at line 76 of file http_tool.c.
References Buffer::buf, cat_Buffer(), copy_i2Buffer(), dup_Buffer(), FALSE, OFF, restore_protocol_header(), TRUE, and Buffer::vldsz.
Referenced by send_http_Buffer(), and send_https_Buffer().
00077 { 00078 Buffer rbd; 00079 int nobody = FALSE; 00080 00081 if (pl==NULL) { 00082 rbd = dup_Buffer(*buf); 00083 return rbd; 00084 } 00085 if (buf==NULL || buf->vldsz<0 || buf->buf==NULL) nobody = TRUE; 00086 00087 if (!nobody) { 00088 // Content-Length の書き換え 00089 tList* pp = pl; 00090 while(pp!=NULL) { 00091 if (!strcasecmp((const char*)(pp->ldat.key.buf), "Content-Length")) { 00092 copy_i2Buffer(buf->vldsz, &(pp->ldat.val)); 00093 break; 00094 } 00095 pp = pp->next; 00096 } 00097 } 00098 00099 rbd = restore_protocol_header(pl, (char*)": ", OFF, NULL); 00100 if (!nobody) cat_Buffer(buf, &rbd); 00101 00102 return rbd; 00103 }
int recv_http_Buffer | ( | int | sofd, | |
tList ** | pl, | |||
Buffer * | buf, | |||
int | tsecond, | |||
int * | hdonly, | |||
int * | state, | |||
int | nochunk | |||
) |
HTTPメッセージを受信して,Buffer変数 *bufに保存する.gzipのエンコード処理は行わない.
bufのバッファ領域は予め確保されていること.
sofd | 接続相手へのソケット | |
[out] | *pl | 受信したヘッダが格納されるリストへのポインタ.必要ないなら NULLでも良い. |
[out] | buf | コンテンツを格納する Buffer変数へのポインタ.バッファ部は予め確保して置く. |
tsecond | 最初の受信までのタイムアウト(s) | |
[out] | hdonly | データがヘッダのみの場合は TRUE, コンテンツもある場合は FALSE.NULLを指定しても良い. |
[out] | state | サーバとの接続状態.接続中なら TRUE.切断した場合は FALSE.NULLを指定しても良い. |
nochunk | chunkデータを処理しない |
0以上 | 受信したコンテンツのサイズ(Byte) | |
JBXL_NET_RECV_ERROR | 受信エラー | |
JBXL_ARGS_ERROR | buf エラー | |
JBXL_NET_RECV_TIMEOUT | タイムアウトした. |
Definition at line 588 of file http_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_http_chunked(), recv_http_closed(), recv_http_content(), recv_http_header(), search_protocol_header(), TRUE, and Buffer::vldsz.
00589 { 00590 int cc=0, hs, len; 00591 int connect; 00592 Buffer cnt; 00593 tList* lp; 00594 00595 if (buf==NULL || buf->buf==NULL) return JBXL_ARGS_ERROR; 00596 if (hdonly!=NULL) *hdonly = FALSE; 00597 00598 clear_Buffer(buf); 00599 00600 // ヘッダの受信 00601 hs = recv_http_header(sofd, &lp, &len, tsecond, NULL, &connect); 00602 if (state!=NULL) *state = connect; 00603 if (hs<=0) return hs; // エラー 00604 if (len==0 || len==HTTP_HEADER_UNKNOWN_LEN) { // ヘッダのみ 00605 if (hdonly!=NULL) *hdonly = TRUE; 00606 if (pl!=NULL) *pl = lp; 00607 else del_tList(&lp); 00608 return hs; 00609 } 00610 00611 // ヘッダ中に紛れ込んだコンテンツの取り出し 00612 cnt = search_protocol_header(lp, (char*)HDLIST_CONTENTS_KEY, 1); 00613 if (cnt.buf!=NULL) { 00614 cc = cnt.vldsz; 00615 hs = hs - cc; 00616 copy_Buffer(&cnt, buf); 00617 free_Buffer(&cnt); 00618 } 00619 00620 if (lp!=NULL && lp->ldat.id==HTTP_UNKNOWN_METHOD) { // not HTTP 00621 *pl = lp; 00622 return cc; 00623 } 00624 00625 // コンテンツの受信 00626 if (connect) { 00627 if (len>0) { 00628 cc = recv_http_content(sofd, buf, len, tsecond, NULL, &connect); 00629 } 00630 else if (len==HTTP_HEADER_CHUNKED) { 00631 connect = HTTP_HEADER_CHUNKED; 00632 if (!nochunk) { 00633 cc = recv_http_chunked(sofd, buf, tsecond, NULL, &connect); 00634 } 00635 } 00636 else { //if (len==HTTP_HEADER_CLOSED_SESSION) { 00637 cc = recv_http_closed(sofd, buf, tsecond, NULL); 00638 connect = FALSE; 00639 } 00640 } 00641 00642 // for Chunked 00643 if (!nochunk && is_http_header_field(lp, (char*)"Transfer-Encoding", (char*)"chunked", 1)) { 00644 delete_protocol_header(&lp, (char*)"Transfer-Encoding", 0); 00645 char* str = itostr_ts(cc); 00646 add_protocol_header(lp, (char*)"Content-Length", str); 00647 freeNull(str); 00648 } 00649 00650 if (pl!=NULL) *pl = lp; 00651 else del_tList(&lp); 00652 if (cc>0) cc = cc + hs; 00653 00654 if (state!=NULL) *state = connect; 00655 return cc; 00656 }
int recv_http_chunked | ( | int | sofd, | |
Buffer * | buf, | |||
int | tm, | |||
FILE * | fp, | |||
int * | state | |||
) |
int recv_http_chunked(int sofd, Buffer* buf, int tm, FILE* fp, int* state)
HTTPメッセージで recv_http_header() で受信したヘッダに引き続いて,Chunkモードのコンテンツデータを受信する.
fp がNULLでなければ,受信データ(コンテンツ)はファイルにも保存される.
sofd | 接続相手へのソケット | |
[in,out] | buf | 全コンテンツを保存する変数.最初に,recv_https_header()で受信したコンテンツ部分を入れて置く. |
tm | タイムアウト秒数. | |
fp | 受信したコンテンツを保存するファイルディスクリプタ.NULLなら保存しない. | |
[out] | state | サーバとの接続状態.接続中なら TRUE.切断した場合は FALSE.NULLを指定しても良い. |
0以上 | 全コンテンツのサイズ(Byte).recv_https_header()で受信したコンテンツ部分を含む. | |
0未満 | エラー |
Definition at line 418 of file http_tool.c.
References Buffer::buf, cat_Buffer(), clear_Buffer(), FALSE, free_Buffer(), get_chunked_size(), make_Buffer(), recv_http_chunked_remain(), RECVBUFSZ, tcp_recv_Buffer_wait(), TRUE, and Buffer::vldsz.
Referenced by recv_http_Buffer(), and recv_http_file().
00419 { 00420 int cc, sz, i; 00421 int chnksz, hdsz, tlsz; 00422 if (state!=NULL) *state = TRUE; 00423 00424 Buffer tmp = make_Buffer(RECVBUFSZ); 00425 00426 sz = buf->vldsz; 00427 if (sz<=0) { // chunk のサイズを含んだデータを読み込む 00428 cc = tcp_recv_Buffer_wait(sofd, &tmp, tm); 00429 if (cc<=0) { 00430 if (state!=NULL) *state = FALSE; 00431 free_Buffer(&tmp); 00432 return cc; 00433 } 00434 } 00435 else { // 既にコンテンツがある場合は tmpへ移動 00436 cat_Buffer(buf, &tmp); 00437 clear_Buffer(buf); 00438 } 00439 00440 // 00441 chnksz = sz = get_chunked_size((char*)tmp.buf, &hdsz, &tlsz); 00442 00443 while (chnksz>0) { 00444 // 00445 if (chnksz+hdsz+tlsz > tmp.vldsz) { 00446 cc = recv_http_chunked_remain(sofd, &tmp, chnksz+hdsz+tlsz, tm); 00447 if (cc<=0) { 00448 sz = cc; 00449 break; 00450 } 00451 } 00452 00453 Buffer cat = tmp; 00454 cat.buf = tmp.buf + hdsz; 00455 cat.vldsz = chnksz; 00456 cat_Buffer(&cat, buf); 00457 //tmp.buf[tmp.vldsz] = '\0'; 00458 00459 // 次の chunk用にデータをつめる 00460 for (i=0; i<tmp.vldsz-chnksz-hdsz-tlsz; i++) { 00461 tmp.buf[i] = tmp.buf[chnksz + hdsz + tlsz + i]; 00462 } 00463 tmp.vldsz = tmp.vldsz - chnksz - hdsz - tlsz; 00464 //tmp.buf[tmp.vldsz] = '\0'; 00465 00466 if (tmp.vldsz==0) { 00467 cc = tcp_recv_Buffer_wait(sofd, &tmp, tm); 00468 if (cc<=0) { 00469 sz = cc; 00470 break; 00471 } 00472 } 00473 chnksz = get_chunked_size((char*)tmp.buf, &hdsz, &tlsz); 00474 sz += chnksz; 00475 } 00476 00477 if (fp!=NULL) fwrite(buf->buf, buf->vldsz, 1, fp); 00478 00479 free_Buffer(&tmp); 00480 return sz; 00481 }
int recv_http_chunked_remain | ( | int | sofd, | |
Buffer * | buf, | |||
int | chnksz, | |||
int | tm | |||
) |
int recv_http_chunked_remain(int sofd, Buffer* buf, int chnksz, int tm)
chunk の残りのデータを読み込む.次の chunkのデータも読み込まれる可能性がある.
sofd | 接続相手へのソケット | |
[in,out] | buf | 残りのコンテンツを保存する変数.最初に,recv_http_header()で受信したコンテンツ部分を入れて置く. |
chnksz | 最低限読み込むべきサイズ.chunkのサイズ | |
tm | タイムアウト秒数. |
1以上 | 読み込んだコンテンツのサイズ(Byte).recv_http_header()で受信したコンテンツ部分を含む. | |
0以下 | エラー |
Definition at line 498 of file http_tool.c.
References cat_Buffer(), free_Buffer(), make_Buffer(), RECVBUFSZ, tcp_recv_Buffer_wait(), and Buffer::vldsz.
Referenced by recv_http_chunked().
00499 { 00500 int cc = 0; 00501 int sz = buf->vldsz; 00502 if (chnksz<=sz) return 0; 00503 00504 Buffer rcv = make_Buffer(RECVBUFSZ); 00505 00506 while (chnksz>sz) { 00507 //memset(rcv.buf, 0, cc); 00508 cc = tcp_recv_Buffer_wait(sofd, &rcv, tm); 00509 if (cc<=0) { 00510 sz = cc; 00511 break; 00512 } 00513 cat_Buffer(&rcv, buf); 00514 sz += cc; 00515 } 00516 00517 free_Buffer(&rcv); 00518 return sz; 00519 }
int recv_http_closed | ( | int | sofd, | |
Buffer * | buf, | |||
int | tm, | |||
FILE * | fp | |||
) |
int recv_http_closed(int sofd, Buffer* buf, int tm, FILE* fp)
HTTPメッセージで recv_http_header() で受信したヘッダに引き続いて,長さ不明のコンテンツデータを受信する. この命令で残りの全てのヘッダを読み込む.
fp がNULLでなければ,受信データ(コンテンツ)はファイルにも保存される.
sofd | 接続相手へのソケット | |
[in,out] | buf | 全コンテンツを保存する変数.最初に,recv_https_header()で受信したコンテンツ部分を入れて置く. |
tm | タイムアウト秒数. | |
fp | 受信したコンテンツを保存するファイルディスクリプタ.NULLなら保存しない. |
0以上 | 全コンテンツのサイズ(Byte).recv_https_header()で受信したコンテンツ部分を含む. | |
0未満 | エラー |
Definition at line 539 of file http_tool.c.
References Buffer::buf, cat_Buffer(), free_Buffer(), JBXL_NET_RECV_TIMEOUT, make_Buffer(), recv_wait(), RECVBUFSZ, tcp_recv_Buffer(), and Buffer::vldsz.
Referenced by recv_http_Buffer(), and recv_http_file().
00540 { 00541 int cc, sz, tout; 00542 Buffer rcv; 00543 00544 sz = buf->vldsz; 00545 00546 rcv = make_Buffer(RECVBUFSZ); 00547 while ((tout=recv_wait(sofd, tm))){ 00548 cc = tcp_recv_Buffer(sofd, &rcv); 00549 if (cc>0) { 00550 if (fp!=NULL) fwrite(rcv.buf, cc, 1, fp); 00551 cat_Buffer(&rcv, buf); 00552 sz += cc; 00553 } 00554 else { 00555 break; 00556 } 00557 //memset(rcv.buf, 0, cc); 00558 } 00559 free_Buffer(&rcv); 00560 00561 if (!tout) return JBXL_NET_RECV_TIMEOUT; 00562 00563 return sz; 00564 }
int recv_http_content | ( | int | sofd, | |
Buffer * | buf, | |||
int | len, | |||
int | tm, | |||
FILE * | fp, | |||
int * | state | |||
) |
int recv_http_content(int sofd, Buffer* buf, int len, int tm, FILE* fp, int* state)
HTTPメッセージで recv_http_header() で受信したヘッダに引き続いて,コンテンツを受信する.
fp がNULLでなければ,受信データ(コンテンツ)はファイルにも保存される.
sofd | 接続相手へのソケット | |
[in,out] | buf | 全コンテンツを保存する変数.最初に,recv_https_header()で受信したコンテンツ部分を入れて置く. |
len | 受信したヘッダの "Content-Length" の値.受信データのサイズのチェックに使用する. | |
tm | タイムアウト秒数. | |
fp | 受信したコンテンツを保存するファイルディスクリプタ.NULLなら保存しない. | |
[out] | state | サーバとの接続状態.接続中なら TRUE.切断した場合は FALSE.NULLを指定しても良い. |
0以上 | 全コンテンツのサイズ(Byte).recv_https_header()で受信したコンテンツ部分を含む. | |
0未満 | エラー |
Definition at line 368 of file http_tool.c.
References Buffer::buf, cat_Buffer(), FALSE, free_Buffer(), make_Buffer(), RECVBUFSZ, tcp_recv_Buffer_wait(), TRUE, and Buffer::vldsz.
Referenced by recv_http_Buffer(), recv_http_file(), and simple_web_proxy().
00369 { 00370 int cc, sz; 00371 Buffer rcv; 00372 00373 if (state!=NULL) *state = TRUE; 00374 00375 sz = buf->vldsz; 00376 if (sz>0 && fp!=NULL) fwrite(buf->buf, sz, 1, fp); 00377 00378 // コンテンツの残りを受信 00379 rcv = make_Buffer(RECVBUFSZ); 00380 while(sz<len) { 00381 // 00382 cc = tcp_recv_Buffer_wait(sofd, &rcv, tm); 00383 if (cc>0) { 00384 if (fp!=NULL) fwrite(rcv.buf, cc, 1, fp); 00385 cat_Buffer(&rcv, buf); 00386 sz += cc; 00387 } 00388 else { 00389 if (state!=NULL) *state = FALSE; 00390 sz = cc; 00391 break; 00392 } 00393 //memset(rcv.buf, 0, cc); 00394 } 00395 free_Buffer(&rcv); 00396 00397 return sz; 00398 }
int recv_http_file | ( | int | sofd, | |
tList ** | pl, | |||
const char * | fname, | |||
const char * | wdir, | |||
int | tsecond, | |||
int * | hdonly, | |||
int * | state | |||
) |
HTTPメッセージを受信して,コンテンツをファイルに保存する.Encodingが gzipの場合は展開する.
sofd | 接続相手へのソケット | |
[out] | *pl | 受信したヘッダが格納されるリストへのポインタ. |
fname | 保存するファイル名 | |
wdir | 作業用ディレクトリを指定.NULLの場合は /tmp になる. | |
tsecond | 最初の受信までのタイムアウト(s) | |
[out] | hdonly | データがヘッダのみの場合は TRUE, コンテンツもある場合は FALSE.NULLを指定しても良い. |
[out] | state | サーバとの接続状態.接続中なら TRUE.切断した場合は FALSE.NULLを指定しても良い. |
1以上 | 受信したファイルのサイズ(Byte)(ヘッダを含む) | |
0 | 正常切断 | |
JBXL_NET_RECV_ERROR | 受信エラー | |
JBXL_NET_RECV_TIMEOUT | タイムアウトした. |
Definition at line 678 of file http_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_http_chunked(), recv_http_closed(), recv_http_content(), recv_http_header(), RECVBUFSZ, search_protocol_header(), TRUE, and Buffer::vldsz.
Referenced by save_http_xml().
00679 { 00680 int cc=0, hs, len; 00681 Buffer buf, cnt; 00682 FILE* fp = NULL; 00683 const char tmpd[] = "/tmp"; 00684 int connect; 00685 00686 if (hdonly!=NULL) *hdonly = FALSE; 00687 00688 // ヘッダの受信 00689 hs = recv_http_header(sofd, pl, &len, tsecond, NULL, &connect); 00690 if (state!=NULL) *state = connect; 00691 if (hs<=0) return hs; // エラー 00692 if (len==0 || len==HTTP_HEADER_UNKNOWN_LEN) { // ヘッダのみ 00693 if (hdonly!=NULL) *hdonly = TRUE; 00694 return hs; 00695 } 00696 00697 // ヘッダ中に紛れ込んだコンテンツの取り出し 00698 buf = make_Buffer(RECVBUFSZ); 00699 cnt = search_protocol_header(*pl, (char*)HDLIST_CONTENTS_KEY, 1); 00700 if (cnt.buf!=NULL) { 00701 /*DEBUG_MODE { 00702 if (len==HTTP_HEADER_CHUNKED) { 00703 char* line = get_line((char*)cnt.buf, 1); 00704 int chnksz = hexstr2i(line); 00705 PRINT_MESG("RECV_HTTP_FILE: INFO: Chunk Size in Header = %d\n", chnksz); 00706 freeNull(line); 00707 } 00708 }*/ 00709 cc = cnt.vldsz; 00710 hs = hs - cc; 00711 copy_Buffer(&cnt, &buf); 00712 free_Buffer(&cnt); 00713 } 00714 00715 // コンテンツの受信 00716 if (connect) { 00717 if (len>0) { 00718 cc = recv_http_content(sofd, &buf, len, tsecond, NULL, &connect); 00719 } 00720 else if (len==HTTP_HEADER_CHUNKED) { 00721 cc = recv_http_chunked(sofd, &buf, tsecond, NULL, &connect); 00722 } 00723 else { //if (len==HTTP_HEADER_CLOSED_SESSION) { 00724 cc = recv_http_closed(sofd, &buf, tsecond, NULL); 00725 connect = FALSE; 00726 } 00727 } 00728 00729 if (cc>0) { 00730 // コンテンツをファイルへ保存 00731 if (fname!=NULL) fp = fopen(fname, "wb"); 00732 if (fp!=NULL) { 00733 fwrite(buf.buf, buf.vldsz, 1, fp); 00734 fclose(fp); 00735 } 00736 free_Buffer(&buf); 00737 00738 // 00739 if (fname!=NULL) { 00740 buf = search_protocol_header(*pl, (char*)"Content-Encoding", 1); 00741 00742 // Encoding 処理 00743 if (buf.buf!=NULL) { 00744 // gzip or deflate 00745 if (!strncasecmp((const char*)buf.buf, "gzip", 4) || 00746 !strncasecmp((const char*)buf.buf, "deflate", 7)) { 00747 #ifdef DISABLE_ZLIB 00748 DEBUG_MODE PRINT_MESG("RECV_HTTP_FILE: WARNING: Content-Encoding is [%s]. But zlib is not installed!!\n", buf.buf); 00749 #else 00750 if (wdir==NULL) wdir = tmpd; 00751 cc = gz_decode_file_replace(fname, wdir); 00752 delete_protocol_header(pl, (char*)"Content-Encoding", 0); 00753 00754 // for chunked 00755 if (is_http_header_field(*pl, (char*)"Transfer-Encoding", (char*)"chunked", 1)) { 00756 delete_protocol_header(pl, (char*)"Transfer-Encoding", 0); 00757 char* str = itostr_ts(cc); 00758 add_protocol_header(*pl, (char*)"Content-Length", str); 00759 freeNull(str); 00760 } 00761 #endif 00762 } 00763 00764 else { 00765 DEBUG_MODE PRINT_MESG("RECV_HTTP_FILE: WARNING: unknown Content-Encoding [%s]\n", buf.buf); 00766 } 00767 00768 free_Buffer(&buf); 00769 } 00770 00771 // No Encofing 00772 else { 00773 // for chunked 00774 if (is_http_header_field(*pl, (char*)"Transfer-Encoding", (char*)"chunked", 1)) { 00775 delete_protocol_header(pl, (char*)"Transfer-Encoding", 0); 00776 char* str = itostr_ts(cc); 00777 add_protocol_header(*pl, (char*)"Content-Length", str); 00778 freeNull(str); 00779 } 00780 } 00781 } 00782 cc = cc + hs; 00783 } 00784 00785 if (state!=NULL) *state = connect; 00786 return cc; 00787 }
int recv_http_header | ( | int | sofd, | |
tList ** | pl, | |||
int * | len, | |||
int | tm, | |||
FILE * | fp, | |||
int * | state | |||
) |
int recv_http_header(int sofd, tList** pl, int* len, int tm, FILE* fp, int* state)
HTTP通信のヘッダ部分を受信して,リストに格納する.
NULLでない fp が指定された場合,受信した全てのデータをファイルに保存する. 受信したデータが HTTPでない場合は,*pl の HDLIST_CONTENTS_KEY の値として受信データを格納する.
sofd | 接続相手へのソケット | |
[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未満). |
tm | タイムアウト秒数. | |
fp | 受信した全てのデータを保存するためのファイルポインタ.NULLの場合は保存しない. | |
[out] | state | サーバとの接続状態.接続中なら TRUE.切断した場合は FALSE.NULLを指定しても良い. |
0以上 | 受信した全バイト数 | |
0 | 正常切断 | |
JBXL_NET_RECV_ERROR | 受信エラー | |
JBXL_ARGS_ERROR | 無効な sofdを指定した または len にNULL を指定した |
Definition at line 246 of file http_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_NET_RECV_ERROR, Loop, make_Buffer(), make_Buffer_str, RECVBUFSZ, search_protocol_header(), strncasecmp_tList(), tcp_recv_Buffer_wait(), TRUE, and Buffer::vldsz.
Referenced by recv_http_Buffer(), recv_http_file(), simple_web_proxy(), and www2browser_relay().
00247 { 00248 int cc, sz, com; 00249 Buffer mbuf; 00250 tList* lp; 00251 int connect = TRUE; 00252 00253 if (sofd<=0) return JBXL_ARGS_ERROR; 00254 if (len==NULL) return JBXL_ARGS_ERROR; 00255 *len = HTTP_HEADER_UNKNOWN_LEN; 00256 00257 mbuf = make_Buffer(RECVBUFSZ); 00258 00259 sz = 0; 00260 lp = NULL; 00261 *pl = NULL; 00262 00263 cc = tcp_recv_Buffer_wait(sofd, &mbuf, tm); 00264 com = get_http_method((char*)mbuf.buf); 00265 00266 if (com>HTTP_UNKNOWN_METHOD) { 00267 Loop { 00268 if (cc>0) { 00269 if (fp!=NULL) fwrite(mbuf.buf, cc, 1, fp); 00270 lp = get_protocol_header_list_seq(lp, mbuf, ':', TRUE, TRUE); 00271 sz += cc; 00272 /* 00273 if (sz==cc) { // is HTTP ? 00274 tList* ll = find_tList_top(lp); 00275 if (get_http_header_method(ll)==HTTP_UNKNOWN_METHOD) { 00276 connect = HTTP_HEADER_NOT_HTTP; 00277 *pl = ll; 00278 break; 00279 } 00280 }*/ 00281 } 00282 else { 00283 connect = FALSE; 00284 break; 00285 } 00286 // 00287 *pl = find_tList_top(lp); 00288 if (strncasecmp_tList(*pl, (char*)HDLIST_END_KEY, 0, 1)!=NULL) break; 00289 // 00290 cc = tcp_recv_Buffer_wait(sofd, &mbuf, tm); 00291 } 00292 } 00293 else { 00294 if (mbuf.vldsz>0) { 00295 Buffer key = make_Buffer_str(HDLIST_CONTENTS_KEY); 00296 *pl = add_tList_node_Buffer(NULL, key, mbuf); 00297 free_Buffer(&key); 00298 } 00299 *len = HTTP_HEADER_NOT_HTTP; 00300 connect = FALSE; 00301 } 00302 00303 free_Buffer(&mbuf); 00304 if (*pl!=NULL) (*pl)->ldat.id = com; 00305 if (state!=NULL) *state = connect; 00306 // 00307 if (sz==0 && cc==0) return 0; // 正常切断 00308 if (sz==0 && cc<0) return JBXL_NET_RECV_ERROR; 00309 if (*pl==NULL) return JBXL_NET_RECV_ERROR; 00310 if (*len==HTTP_HEADER_NOT_HTTP) return cc; 00311 00312 // コンテンツの長さを得る. 00313 /* 00314 Buffer hbuf = search_protocol_header(*pl, (char*)HDLIST_FIRST_LINE_KEY, 1); 00315 if (hbuf.buf!=NULL) { 00316 if (!strncasecmp((char*)hbuf.buf, "GET ", 4)) { 00317 *len = 0; 00318 } 00319 free_Buffer(&hbuf); 00320 }*/ 00321 00322 if (com==HTTP_GET_METHOD) *len = 0; 00323 00324 if (*len==HTTP_HEADER_UNKNOWN_LEN) { 00325 if (is_http_header_field(*pl, (char*)"Transfer-Encoding", (char*)"chunked", 1)) { 00326 *len = HTTP_HEADER_CHUNKED; 00327 } 00328 } 00329 00330 if (*len==HTTP_HEADER_UNKNOWN_LEN) { 00331 Buffer hbuf = search_protocol_header(*pl, (char*)"Content-Length", 1); 00332 if (hbuf.buf!=NULL) { 00333 *len = atoi((const char*)hbuf.buf); 00334 free_Buffer(&hbuf); 00335 } 00336 } 00337 00338 if (*len==HTTP_HEADER_UNKNOWN_LEN) { 00339 if (get_http_version_num(*pl)<=1.0 && get_http_status_num(*pl)>=200) { 00340 if (is_http_header_field(*pl, (char*)"Connection", (char*)"close", 1)) { 00341 *len = HTTP_HEADER_CLOSED_SESSION; 00342 } 00343 } 00344 } 00345 00346 return sz; 00347 }
int save_http_xml | ( | int | cofd, | |
tList ** | pl, | |||
tXML ** | xml, | |||
char ** | recvfn, | |||
const char * | wdir, | |||
int | timeout, | |||
int * | state | |||
) |
受信した XML通信データをファイルに保存
cofd | 接続相手へのソケット | |
[out] | *pl | 受信したヘッダが格納されるリストへのポインタ. |
[out] | *xml | パースされたデータが格納されるXML構造体へのポインタ |
[out] | *recvfn | 保存するファイル名 |
wdir | 作業用ディレクトリを指定する.NULLの場合は /tmp になる. | |
timeout | 最初の受信までのタイムアウト(s) | |
[out] | state | サーバとの接続状態.接続中なら TRUE.切断した場合は FALSE.NULLを指定しても良い. |
1以上 | 受信したファイルのサイズ(Byte)(ヘッダを含む) | |
0 | 正常切断 | |
JBXL_NET_RECV_ERROR | 受信エラー | |
JBXL_NET_RECV_TIMEOUT | タイムアウトした. |
Definition at line 809 of file http_tool.c.
References del_xml, free_Buffer(), JBXL_NET_RECV_ERROR, recv_http_file(), search_protocol_header(), temp_filename(), WORK_FILENAME_LEN, and xml_parse_file().
00810 { 00811 int header; 00812 00813 if (pl==NULL || recvfn==NULL) return 0; 00814 00815 *pl = NULL; 00816 if (xml!=NULL) *xml = NULL; 00817 *recvfn = temp_filename(wdir, WORK_FILENAME_LEN); 00818 00819 int cc = recv_http_file(cofd, pl, *recvfn, wdir, timeout, &header, state); 00820 if (cc<=0 || *pl==NULL) { 00821 free(*recvfn); 00822 *recvfn = NULL; 00823 if (cc==0) return 0; 00824 return JBXL_NET_RECV_ERROR; 00825 } 00826 00827 if (header) { 00828 free(*recvfn); 00829 *recvfn = NULL; 00830 } 00831 else { 00832 if (xml!=NULL && *pl!=NULL && *recvfn!=NULL && cc>0) { 00833 Buffer buf = search_protocol_header(*pl, (char*)"Content-Type", 1); 00834 *xml = xml_parse_file(*recvfn); 00835 if (*xml!=NULL && (*xml)->state<0) del_xml(xml); 00836 free_Buffer(&buf); 00837 } 00838 } 00839 00840 return cc; 00841 }
int send_http_Buffer(int sofd, tList* pl, Buffer* buf)
ヘッダとバッファの内容を HTTP通信で送信する.
sofd | 接続相手へのソケット | |
pl | ファイルに先立って送信されるヘッダが格納されるリストへのポインタ. | |
buf | 送信するコンテンツが格納された Buffer変数へのポインタ. |
0以上 | 送信したデータの全サイズ(Byte) | |
JBXL_ARGS_ERROR | リストへのポインタが NULL |
Definition at line 120 of file http_tool.c.
References free_Buffer(), rebuild_http_Buffer(), and tcp_send_Buffer().
00121 { 00122 int sz; 00123 Buffer snd; 00124 /* 00125 int nobody = FALSE; 00126 00127 if (pl==NULL) return JBXL_ARGS_ERROR; 00128 if (buf==NULL || buf->vldsz<0 || buf->buf==NULL) nobody = TRUE; 00129 00130 if (!nobody) { 00131 // Content-Length の書き換え 00132 tList* pp = pl; 00133 while(pp!=NULL) { 00134 if (!strcasecmp((const char*)(pp->ldat.key.buf), "Content-Length")) { 00135 copy_i2Buffer(buf->vldsz, &(pp->ldat.val)); 00136 break; 00137 } 00138 pp = pp->next; 00139 } 00140 } 00141 00142 snd = restore_protocol_header(pl, (char*)": ", OFF, NULL); 00143 if (!nobody) cat_Buffer(buf, &snd); 00144 */ 00145 00146 snd = rebuild_http_Buffer(pl, buf); 00147 sz = tcp_send_Buffer(sofd, &snd); 00148 free_Buffer(&snd); 00149 00150 return sz; 00151 }
int send_http_file | ( | int | sofd, | |
tList * | pl, | |||
const char * | fname | |||
) |
int send_http_file(int sofd, tList* pp, const char* fname)
ヘッダとファイルの内容を HTTP通信で送信する.
sofd | 接続相手へのソケット | |
pl | ファイルに先立って送信されるヘッダが格納されるリストへのポインタ. | |
fname | 送信するファイル名.ヘッダのみ送る場合は NULL |
0以上 | 送信したデータの全サイズ(Byte) | |
JBXL_ARGS_ERROR | リストへのポインタが NULL | |
JBXL_MALLOC_ERROR | メモリ確保エラー |
Definition at line 168 of file http_tool.c.
References cat_b2Buffer(), copy_s2Buffer, file_size(), free_Buffer(), JBXL_ARGS_ERROR, JBXL_MALLOC_ERROR, OFF, restore_protocol_header(), tcp_send_Buffer(), and UNUSED.
00169 { 00170 int sz = 0; 00171 FILE* fp = NULL; 00172 char num[20]; 00173 tList* pp; 00174 unsigned char* html; 00175 Buffer buf; 00176 00177 size_t rs; 00178 UNUSED(rs); 00179 00180 if (pl==NULL) return JBXL_ARGS_ERROR; 00181 if (fname!=NULL) sz = file_size((char*)fname); 00182 if (sz<=0) sz = 0; 00183 snprintf(num, 18, "%d", sz); 00184 00185 // Content-Length の書き換え 00186 pp = pl; 00187 while(pp!=NULL) { 00188 if (!strcasecmp((const char*)(pp->ldat.key.buf), "Content-Length")) { 00189 copy_s2Buffer(num, &(pp->ldat.val)); 00190 break; 00191 } 00192 pp = pp->next; 00193 } 00194 00195 buf = restore_protocol_header(pl, (char*)": ", OFF, NULL); 00196 00197 if (fname!=NULL && sz!=0) fp = fopen(fname, "rb"); 00198 if (fp!=NULL) { 00199 html = (unsigned char*)malloc(sz+1); 00200 if (html==NULL) { 00201 fclose(fp); 00202 free_Buffer(&buf); 00203 return JBXL_MALLOC_ERROR; 00204 } 00205 00206 memset(html, 0, sz+1); 00207 rs = fread(html, sz, 1, fp); 00208 fclose(fp); 00209 00210 cat_b2Buffer(html, &buf, sz); 00211 free(html); 00212 } 00213 00214 sz = tcp_send_Buffer(sofd, &buf); 00215 free_Buffer(&buf); 00216 00217 return sz; 00218 }
int send_http_header | ( | int | sofd, | |
tList * | pp, | |||
int | mode | |||
) |
int send_http_header(int sofd, tList* pp, int mode)
ヘッダリストの内容を HTTP通信で送信する. ヘッダ中の Content-Length の値は操作しない.
sofd | 接続相手へのソケット | |
pp | 送信するヘッダが格納されるリストへのポインタ. | |
mode | ON: ヘッダリスト内にコンテンツの一部があればそれも送信する. | |
mode | OFF: ヘッダリスト内にコンテンツの一部があっても送信しない. |
0以上 | mode==OFF: 送信した全データバイト数. mode==ON : 送信したコンテンツのバイト数. | |
0未満 | エラー | |
JBXL_ARGS_ERROR | リストへのポインタが NULL |
tList* http_header = NULL; tList* http_length = NULL; tList* http_data = NULL; tList* pp = NULL; pp = http_header = add_tList_node_bystr(pp, 0, 0, HDLIST_FIRST_LINE_KEY, "POST /test.php HTTP/1.1", NULL, 0); pp = add_tList_node_bystr(pp, 0, 0, "Content-Type", "application/x-www-form-urlencoded", NULL, 0); pp = add_tList_node_bystr(pp, 0, 0, "Connection", "close", NULL, 0); pp = http_length = add_tList_node_bystr(pp, 0, 0, "Content-Length", "", NULL, 0); pp = add_tList_node_bystr(pp, 0, 0, HDLIST_END_KEY, "", NULL, 0); pp = http_data = add_tList_node_bystr(pp, 0, 0, HDLIST_CONTENTS_KEY, "", NULL, 0); copy_i2Buffer((int)buf.vldsz, &(http_length->ldat.val)); copy_Buffer(&buf, &(http_data->ldat.val)); send_http_header(sock, http_header, ON);
Definition at line 57 of file http_tool.c.
References free_Buffer(), JBXL_ARGS_ERROR, ON, restore_protocol_header(), tcp_send_Buffer(), and Buffer::vldsz.
Referenced by simple_web_proxy(), and www2browser_relay().
00058 { 00059 int hs=0, sz=0; 00060 Buffer buf; 00061 00062 if (pp==NULL) return JBXL_ARGS_ERROR; 00063 00064 buf = restore_protocol_header(pp, (char*)": ", mode, &hs); 00065 if (buf.vldsz>0) { 00066 sz = tcp_send_Buffer(sofd, &buf); 00067 if (mode==ON) sz = sz - hs; 00068 } 00069 00070 free_Buffer(&buf); 00071 return sz; 00072 }
void send_http_passwd_req | ( | int | sock | ) |
Definition at line 1532 of file http_tool.c.
References tcp_send().
01533 { 01534 tcp_send(sofd, (char*)"HTTP/1.1 401 Authorization Required\r\n", 0); 01535 tcp_send(sofd, (char*)"WWW-Authenticate: Basic realm=\"TTS\"\r\n", 0); 01536 tcp_send(sofd, (char*)"Pragma: no-cache\r\n", 0); 01537 tcp_send(sofd, (char*)"Cache-Control: no-cache\r\n", 0); 01538 tcp_send(sofd, (char*)"Connection: Close\r\n", 0); 01539 tcp_send(sofd, (char*)"Content-Length: 0\r\n", 0); 01540 tcp_send(sofd, (char*)"Content-Type: text/html\r\n\r\n", 0); 01541 01542 return; 01543 }
int send_http_res_file | ( | int | sock, | |
char * | fn, | |||
int | mode | |||
) |
Definition at line 1483 of file http_tool.c.
References file_size(), HTTP_CONNECTION_CLOSE, JBXL_FILE_OPEN_ERROR, JBXL_MALLOC_ERROR, LBUF, tcp_send(), and UNUSED.
01484 { 01485 int sz; 01486 FILE* fp; 01487 char buf[LBUF]; 01488 char* html; 01489 size_t rs; 01490 UNUSED(rs); 01491 01492 sz = file_size(fname); 01493 if (sz<=0) { 01494 sz = 0; 01495 mode = HTTP_CONNECTION_CLOSE; 01496 } 01497 01498 tcp_send(sofd, (char*)"HTTP/1.1 200 OK\r\n", 0); 01499 tcp_send(sofd, (char*)"Accept-Ranges: bytes\r\n", 0); 01500 tcp_send(sofd, (char*)"Pragma: no-cache\r\n", 0); 01501 tcp_send(sofd, (char*)"Cache-Control: no-cache\r\n", 0); 01502 memset(buf, 0, LBUF); 01503 snprintf(buf, LBUF-2, "Content-Length: %d\r\n", sz); 01504 tcp_send(sofd, buf, 0); 01505 if (mode==HTTP_CONNECTION_CLOSE) tcp_send(sofd, (char*)"Connection: Close\r\n", 0); 01506 else { 01507 tcp_send(sofd, (char*)"Keep-Alive: timeout=1800, max=100\r\n", 0); 01508 tcp_send(sofd, (char*)"Connection: Keep-Alive\r\n", 0); 01509 } 01510 tcp_send(sofd, (char*)"\r\n", 0); 01511 01512 if (sz!=0) fp = fopen(fname, "rb"); 01513 else fp = NULL; 01514 if (fp==NULL) return JBXL_FILE_OPEN_ERROR; 01515 01516 html = (char*)malloc(sz); 01517 if (html==NULL) { 01518 fclose(fp); 01519 return JBXL_MALLOC_ERROR; 01520 } 01521 01522 rs = fread(html, sz, 1, fp); 01523 tcp_send(sofd, html, sz); 01524 fclose(fp); 01525 01526 free(html); 01527 return sz; 01528 }
void set_http_host_header | ( | tList * | pl, | |
char * | hname, | |||
unsigned short | hport | |||
) |
void set_http_host_header(tList* pl, const char* hname, unsigned short hport)
HTTPのヘッダ(pl)の Hostを hname:hport に書き換える. Hostヘッダが無い場合は,最後に追加.
Definition at line 933 of file http_tool.c.
References Buffer::buf, cat_s2Buffer, copy_s2Buffer, free_Buffer(), LBUF, LEN_INT, make_Buffer(), ON, and set_protocol_header().
00934 { 00935 Buffer buf; 00936 char num[LEN_INT]; 00937 00938 if (pl==NULL) return; 00939 00940 buf = make_Buffer(LBUF); 00941 snprintf(num, LEN_INT-1, "%d", hport); 00942 copy_s2Buffer(hname, &buf); 00943 cat_s2Buffer (":", &buf); 00944 cat_s2Buffer (num, &buf); 00945 00946 set_protocol_header(pl, (char*)"Host", (char*)buf.buf, 1, ON); 00947 00948 free_Buffer(&buf); 00949 return; 00950 }
void simple_web_proxy | ( | int | bofd, | |
char * | myip, | |||
int | tmout | |||
) |
void simple_web_proxy(int bofd, char* myip, int tmout)
簡易WEBプロキシ.WWW通信をリレーする.
全てのHTTPプロトコルをサポートしている訳ではない. 接続はできる限りの範囲でしか維持しない.
bofd | ブラウザとの通信ソケット | |
myip | 自分のIPアドレス. | |
tmout | タイムアウト(sec) |
Definition at line 1064 of file http_tool.c.
References Buffer::buf, del_tList(), free_Buffer(), freeNull, get_ipaddr_byname(), http_proxy_header_analyze(), HTTP_PROXY_TIMEOUT, make_Buffer(), make_Buffer_bystr, Min, ON, recv_http_content(), recv_http_header(), RECVBUFSZ, send_http_header(), socket_close(), BVHData::state, tcp_client_socket, tcp_relay(), tcp_send(), tcp_send_Buffer(), TRUE, and www2browser_relay().
01065 { 01066 int wofd = 0; 01067 int len, nd, cc, state; 01068 int btm, wtm, keep; 01069 char* ipa; 01070 tList* pl; 01071 01072 unsigned short sport = 0; 01073 Buffer server, com; 01074 01075 fd_set mask; 01076 struct timeval timeout; 01077 01078 //DEBUG_MODE PRINT_MESG("[%d] SIMPLE_WEB_PROXY: Start Simple WEB Proxy.\n", (int)getpid()); 01079 01080 //init_rand(); 01081 if (tmout<0) tmout = HTTP_PROXY_TIMEOUT; 01082 btm = wtm = tmout; 01083 keep = TRUE; 01084 01085 do { 01086 timeout.tv_sec = btm*10; 01087 timeout.tv_usec = 0; 01088 FD_ZERO(&mask); 01089 FD_SET(bofd, &mask); 01090 nd = select(bofd+1, &mask, NULL, NULL, &timeout); 01091 } while (nd<0); 01092 01093 while (FD_ISSET(bofd, &mask) && keep) { 01094 cc = recv_http_header(bofd, &pl, &len, tmout, NULL, &state); 01095 if (cc<=0) break; 01096 if (pl==NULL) break; 01097 01098 /* 01099 DEBUG_MODE { 01100 PRINT_MESG("[%d] --- Web Proxy Request ---\n", getpid()); 01101 print_tList(stderr, pl); 01102 PRINT_MESG("\n"); 01103 }*/ 01104 01105 com = http_proxy_header_analyze(pl, &server, &sport, &btm, &keep); 01106 if (btm==0) btm = tmout; 01107 else btm = Min(btm, 60); 01108 01109 wofd = 0; 01110 if (server.buf!=NULL && sport!=0) { 01111 ipa = get_ipaddr_byname((char*)server.buf, AF_INET); 01112 if (ipa!=NULL && !strcmp(ipa, myip)) { 01113 free_Buffer(&server); 01114 server = make_Buffer_bystr("127.0.0.1"); 01115 } 01116 freeNull(ipa); 01117 01118 wofd = tcp_client_socket((char*)server.buf, sport); 01119 free_Buffer(&server); 01120 } 01121 01122 if (wofd<=0) { 01123 free_Buffer(&com); 01124 del_tList(&pl); 01125 break; 01126 } 01127 01128 // for HTTPS 01129 if (com.buf!=NULL && !strcasecmp((char*)com.buf, "CONNECT")) { 01130 cc = tcp_send(bofd, (char*)"HTTP/1.1 200 Connection established.\r\nProxy-Connection: close\r\n\r\n", 0); 01131 cc = tcp_relay(bofd, wofd, 5); 01132 01133 del_tList(&pl); 01134 free_Buffer(&com); 01135 break; 01136 } 01137 free_Buffer(&com); 01138 01139 cc = send_http_header(wofd, pl, ON); 01140 if (cc<len && state) { 01141 Buffer buf = make_Buffer(RECVBUFSZ); 01142 cc = recv_http_content(bofd, &buf, len-cc, wtm, NULL, &state); 01143 if (cc<=0) { 01144 del_tList(&pl); 01145 break; 01146 } 01147 01148 tcp_send_Buffer(wofd, &buf); 01149 free_Buffer(&buf); 01150 } 01151 del_tList(&pl); 01152 01153 cc = www2browser_relay(bofd, wofd, btm, wtm, keep); 01154 if (cc<=0) break; 01155 01156 do { 01157 timeout.tv_sec = btm; 01158 timeout.tv_usec = 0; 01159 FD_ZERO(&mask); 01160 FD_SET(bofd, &mask); 01161 nd = select(bofd+1, &mask, NULL, NULL, &timeout); 01162 } while (nd<0); 01163 } 01164 01165 socket_close(wofd); 01166 01167 return; 01168 }
int tcp_relay | ( | int | sofd, | |
int | cofd, | |||
int | tm | |||
) |
int tcp_relay(int sofd, int cofd, int tm)
TCP通信をリレーする.
sofd | クライアント側ソケット | |
cofd | サーバ側ソケット | |
tm | タイムアウト時間(sec) |
0以上 | 転送したバイト数 | |
0未満 | エラー | |
JBXL_NET_RECV_TIMEOUT | タイムアウト |
Definition at line 1359 of file http_tool.c.
References free_Buffer(), JBXL_NET_RECV_TIMEOUT, make_Buffer(), Max, RECVBUFSZ, tcp_recv_Buffer(), and tcp_send_Buffer().
Referenced by simple_web_proxy().
01360 { 01361 int num, nd, cx, cc = JBXL_NET_RECV_TIMEOUT; 01362 Buffer buf; 01363 fd_set mask; 01364 struct timeval timeout; 01365 01366 buf = make_Buffer(RECVBUFSZ); 01367 num = Max(sofd, cofd); 01368 01369 do { 01370 timeout.tv_sec = tm; 01371 timeout.tv_usec = 0; 01372 FD_ZERO(&mask); 01373 FD_SET(sofd, &mask); 01374 FD_SET(cofd, &mask); 01375 nd = select(num+1, &mask, NULL, NULL, &timeout); 01376 } while (nd<0); 01377 01378 //while (FD_ISSET(cofd, &mask) || FD_ISSET(sofd, &mask)) { 01379 while (nd>0 && (FD_ISSET(cofd, &mask) || FD_ISSET(sofd, &mask))) { 01380 01381 if (FD_ISSET(cofd, &mask)) { 01382 cc = tcp_recv_Buffer(cofd, &buf); 01383 if (cc>0) { 01384 cx = tcp_send_Buffer(sofd, &buf); 01385 if (cx<=0) { 01386 cc = cx; 01387 break; 01388 } 01389 } 01390 else break; 01391 //memset(buf.buf, 0, cc); 01392 } 01393 01394 if (FD_ISSET(sofd, &mask)) { 01395 cc = tcp_recv_Buffer(sofd, &buf); 01396 if (cc>0) { 01397 cx = tcp_send_Buffer(cofd, &buf); 01398 if (cx<=0) { 01399 cc = cx; 01400 break; 01401 } 01402 } 01403 else break; 01404 //memset(buf.buf, 0, cc); 01405 } 01406 01407 do { 01408 timeout.tv_sec = tm; 01409 timeout.tv_usec = 0; 01410 FD_ZERO(&mask); 01411 FD_SET(sofd, &mask); 01412 FD_SET(cofd, &mask); 01413 nd = select(num+1, &mask, NULL, NULL, &timeout); 01414 } while (nd<0); 01415 } 01416 01417 free_Buffer(&buf); 01418 01419 if (!FD_ISSET(cofd, &mask) && !FD_ISSET(sofd, &mask)) return JBXL_NET_RECV_TIMEOUT; 01420 return cc; 01421 }
int www2browser_relay | ( | int | bofd, | |
int | wofd, | |||
int | btm, | |||
int | wtm, | |||
int | keep | |||
) |
int www2browser_relay(int bofd, int wofd, int btm, int wtm, int keep)
WWW -> Browser の通信をリレーする.
bofd | ブラウザ側のソケット | |
wofd | WWWサーバ側のソケット | |
btm | ブラウザとのタイムアウト | |
wtm | WWWサーバとのタイムアウト | |
keep | TRUE 接続を(可能な限り)維持する | |
keep | FALSE 接続を維持しない. |
0未満 | エラー | |
JBXL_NET_RECV_TIMEOUT | タイムアウト |
Definition at line 1262 of file http_tool.c.
References add_tList_node_str, del_tList(), free_Buffer(), HDLIST_END_KEY, HTTP_HEADER_CHUNKED, HTTP_HEADER_CLOSED_SESSION, JBXL_NET_RECV_ERROR, JBXL_NET_RECV_TIMEOUT, make_Buffer(), ON, recv_http_header(), recv_wait(), RECVBUFSZ, send_http_header(), strncasecmp_tList(), tcp_recv_Buffer(), and tcp_send_Buffer().
Referenced by simple_web_proxy().
01263 { 01264 int len, cc, cx, sz, tout, state; 01265 Buffer buf; 01266 tList* pl; 01267 tList* lst; 01268 01269 if (!recv_wait(wofd, wtm*10)) return JBXL_NET_RECV_TIMEOUT; 01270 cc = recv_http_header(wofd, &pl, &len, wtm, NULL, &state); 01271 if (cc<=0) { 01272 if (pl!=NULL) del_tList(&pl); 01273 return cc; 01274 } 01275 if (pl==NULL) return JBXL_NET_RECV_ERROR; 01276 01277 /* 01278 DEBUG_MODE { 01279 PRINT_MESG("[%d] --- Web Proxy Response --\n", getpid()); 01280 print_tList(stderr, pl); 01281 PRINT_MESG("\n"); 01282 }*/ 01283 01284 lst = strncasecmp_tList(pl, (char*)HDLIST_END_KEY, 0, 1); 01285 if (lst!=NULL && lst->prev!=NULL) { 01286 if (keep) { 01287 char pxcn[48]; 01288 snprintf(pxcn, 46, "keep-alive, timeout=%d", btm); 01289 add_tList_node_str(lst->prev, "Proxy-Connection", pxcn); 01290 } 01291 else { 01292 add_tList_node_str(lst->prev, "Proxy-Connection", "close"); 01293 } 01294 } 01295 01296 sz = cx = send_http_header(bofd, pl, ON); 01297 del_tList(&pl); 01298 01299 if (len>0) { 01300 buf = make_Buffer(RECVBUFSZ); 01301 while(sz<len) { 01302 if (!recv_wait(wofd, wtm)) { 01303 free_Buffer(&buf); 01304 return JBXL_NET_RECV_TIMEOUT; 01305 } 01306 cc = tcp_recv_Buffer(wofd, &buf); 01307 if (cc>0) { 01308 sz += cc; 01309 cx = tcp_send_Buffer(bofd, &buf); 01310 if (cx<=0) break; 01311 } 01312 else break; 01313 } 01314 01315 free_Buffer(&buf); 01316 if (cc<=0 || (cc>0&&cx<=0)) return 0; 01317 } 01318 01319 else if (len==HTTP_HEADER_CHUNKED || len==HTTP_HEADER_CLOSED_SESSION) { 01320 buf = make_Buffer(RECVBUFSZ); 01321 while ((tout=recv_wait(wofd, 1))){ 01322 cc = tcp_recv_Buffer(wofd, &buf); 01323 if (cc>0) { 01324 sz += cc; 01325 cx = tcp_send_Buffer(bofd, &buf); 01326 if (cx<=0) break; 01327 } 01328 else break; 01329 } 01330 01331 free_Buffer(&buf); 01332 if (!tout) return JBXL_NET_RECV_TIMEOUT; 01333 return 0; 01334 } 01335 01336 return sz; 01337 }