📄 ncbi_connutil.c
字号:
if (!eot || eot >= newline + newlinelen || !(newtaglen = (size_t)(eot - newline))) continue; newtagval = newline + newtaglen + 1; while (newtagval < newline + newlinelen) { if (isspace((unsigned char)(*newtagval))) newtagval++; else break; } switch (op) { case eUserHeaderOp_Delete: len = 0; break; case eUserHeaderOp_Extend: len = newlinelen - (size_t)(newtagval - newline); break; case eUserHeaderOp_Override: len = newtagval < newline + newlinelen ? newlinelen : 0; break; default: assert(0); retval = 0/*failure*/; len = 0; break; } for (line = hdr; *line; line += linelen) { size_t taglen; eol = strchr(line, '\n'); eot = strchr(line, ':'); linelen = (size_t)(eol ? eol - line + 1 : hdr + hdrlen - line); if (!eot || eot >= line + linelen) continue; taglen = (size_t)(eot - line); if (newtaglen != taglen || strncasecmp(newline, line, taglen) != 0) continue; if (op == eUserHeaderOp_Extend) { l = linelen + len; if (len && linelen > 1 && line[linelen - 2] == '\r') --l; } else l = len; if (l != linelen) { size_t off = (size_t)(line - hdr); if (l > linelen) { char* temp = (char*)realloc(hdr, hdrlen + l - linelen + 1); if (!temp) { retval = 0/*failure*/; continue; } hdr = temp; line = temp + off; } hdrlen -= linelen; memmove(line + l, line + linelen, hdrlen - off + 1); hdrlen += l; } if (len) { if (op == eUserHeaderOp_Extend) { char* s = &line[l - len - 1]; *s++ = ' '; memcpy(s, newtagval, len); } else memcpy(line, newline, len); linelen = l; used = 1; } } if (op == eUserHeaderOp_Delete) continue; if (used || !len) { memmove(newline, newline + newlinelen, newhdrlen - (size_t)(newline-new_header) - newlinelen + 1); newhdrlen -= newlinelen; newlinelen = 0; } } info->http_user_header = hdr; if (op != eUserHeaderOp_Delete) { if (!ConnNetInfo_AppendUserHeader(info, new_header)) retval = 0/*failure*/; free(new_header); } return retval;}extern int/*bool*/ ConnNetInfo_OverrideUserHeader(SConnNetInfo* info, const char* header){ return s_ModifyUserHeader(info, header, eUserHeaderOp_Override);}extern void ConnNetInfo_DeleteUserHeader(SConnNetInfo* info, const char* header){ verify(s_ModifyUserHeader(info, header, eUserHeaderOp_Delete));}extern int/*bool*/ ConnNetInfo_ExtendUserHeader(SConnNetInfo* info, const char* header){ return s_ModifyUserHeader(info, header, eUserHeaderOp_Extend);}extern int/*bool*/ ConnNetInfo_AppendArg(SConnNetInfo* info, const char* arg, const char* val){ const char* amp = "&"; if (!arg || !*arg) return 1/*success*/; if (!info->args[0]) amp = ""; if (strlen(info->args) + strlen(amp) + strlen(arg) + (val ? 1 + strlen(val) : 0) >= sizeof(info->args)) return 0/*failure*/; strcat(info->args, amp); strcat(info->args, arg); if (!val || !*val) return 1/*success*/; strcat(info->args, "="); strcat(info->args, val); return 1/*success*/;}extern int/*bool*/ ConnNetInfo_PrependArg(SConnNetInfo* info, const char* arg, const char* val){ char amp = '&'; size_t off; if (!arg || !*arg) return 1/*success*/; if (!info->args[0]) amp = '\0'; off = strlen(arg) + (val && *val ? 1 + strlen(val) : 0) + (amp ? 1 : 0); if (off + strlen(info->args) >= sizeof(info->args)) return 0/*failure*/; if (amp) memmove(&info->args[off], info->args, strlen(info->args) + 1); strcpy(info->args, arg); if (val && *val) { strcat(info->args, "="); strcat(info->args, val); } if (amp) info->args[off - 1] = amp; return 1/*success*/;}extern void ConnNetInfo_DeleteArg(SConnNetInfo* info, const char* arg){ size_t argnamelen; size_t arglen; char* a; if (!arg || !(argnamelen = strcspn(arg, "=&"))) return; for (a = info->args; *a; a += arglen) { if (*a == '&') a++; arglen = strcspn(a, "&"); if (arglen < argnamelen || strncmp(a, arg, argnamelen) != 0 || (a[argnamelen] && a[argnamelen] != '=' && a[argnamelen] != '&')) continue; if (a[arglen]) { arglen++; /* for intermediary args, eat '&' separator, too */ memmove(a, a + arglen, strlen(a + arglen) + 1); } else if (a != info->args) { *--a = '\0'; /* last argument in a list: remove trailing '&' */ } else { *a = '\0'; /* last and the only argument removed */ } arglen = 0; }}extern int/*bool*/ ConnNetInfo_PreOverrideArg(SConnNetInfo* info, const char* arg, const char* val){ if (!arg || !*arg) return 1/*success*/; ConnNetInfo_DeleteArg(info, arg); return ConnNetInfo_PrependArg(info, arg, val);}extern int/*bool*/ ConnNetInfo_PostOverrideArg(SConnNetInfo* info, const char* arg, const char* val){ if (!arg || !*arg) return 1/*success*/; ConnNetInfo_DeleteArg(info, arg); return ConnNetInfo_AppendArg(info, arg, val);}extern SConnNetInfo* ConnNetInfo_Clone(const SConnNetInfo* info){ SConnNetInfo* x_info; if (!info) return 0; x_info = (SConnNetInfo*) malloc(sizeof(SConnNetInfo) + (info->service ? strlen(info->service) + 1 : 0)); *x_info = *info; if (info->timeout && info->timeout != kDefaultTimeout) { x_info->tmo = *info->timeout; x_info->timeout = &x_info->tmo; } if (info->service) { char* s = (char*) x_info + sizeof(*x_info); strcpy(s, info->service); x_info->service = s; } x_info->http_user_header = 0; ConnNetInfo_SetUserHeader(x_info, info->http_user_header); return x_info;}static void s_SaveString(char* s, const char* name, const char* str) { sprintf(s + strlen(s), "%-16.16s: %s%s%s\n", name, str ? "\"" : "", str ? str : "NULL", str ? "\"" : "");}static void s_SaveULong(char* s, const char* name, unsigned long lll) { sprintf(s + strlen(s), "%-16.16s: %lu\n", name, lll);}static void s_SaveBool(char* s, const char* name, int/*bool*/ bbb) { sprintf(s + strlen(s), "%-16.16s: %s\n", name, bbb ? "TRUE" : "FALSE");}extern void ConnNetInfo_Log(const SConnNetInfo* info, LOG lg){ char* s; if (!lg) return; if (!info) { LOG_Write(lg, eLOG_Trace, 0, 0, 0, "ConnNetInfo_Log: NULL info"); return; } if (!(s = (char*) malloc(sizeof(*info) + 4096 + (info->service ? strlen(info->service) : 0) + (info->http_user_header ? strlen(info->http_user_header) : 0)))) { LOG_WRITE(lg, eLOG_Error, "ConnNetInfo_Log: Cannot alloc temp buffer"); return; } strcpy(s, "ConnNetInfo_Log\n" "#################### [BEGIN] SConnNetInfo:\n"); s_SaveString (s, "service", info->service); s_SaveString (s, "client_host", info->client_host); s_SaveString (s, "host", info->host); s_SaveULong (s, "port", info->port); s_SaveString (s, "path", info->path); s_SaveString (s, "args", info->args); s_SaveString (s, "req_method", (info->req_method == eReqMethod_Any ? DEF_CONN_REQ_METHOD : (info->req_method == eReqMethod_Get ? "GET" : (info->req_method == eReqMethod_Post ? "POST" : "Unknown")))); if (info->timeout) { s_SaveULong (s, "timeout(sec)", info->timeout->sec); s_SaveULong (s, "timeout(usec)", info->timeout->usec); } else s_SaveString(s, "timeout", "infinite"); s_SaveULong (s, "max_try", info->max_try); s_SaveString (s, "http_proxy_host", info->http_proxy_host); s_SaveULong (s, "http_proxy_port", info->http_proxy_port); s_SaveString (s, "proxy_host", info->proxy_host); s_SaveString (s, "debug_printout", (info->debug_printout == eDebugPrintout_None ? "NONE" : (info->debug_printout == eDebugPrintout_Some ? "SOME" : (info->debug_printout == eDebugPrintout_Data ? "DATA" : "Unknown")))); s_SaveBool (s, "stateless", info->stateless); s_SaveBool (s, "firewall", info->firewall); s_SaveBool (s, "lb_disable", info->lb_disable); s_SaveString (s, "user_header", info->http_user_header); s_SaveBool (s, "proxy_adjusted", info->http_proxy_adjusted); strcat(s, "#################### [END] SConnNetInfo\n"); LOG_Write(lg, eLOG_Trace, 0, 0, 0, s); free(s);}extern void ConnNetInfo_Destroy(SConnNetInfo* info){ if (!info) return; ConnNetInfo_SetUserHeader(info, 0); free(info);}extern SOCK URL_Connect(const char* host, unsigned short port, const char* path, const char* args, EReqMethod req_method, size_t content_length, const STimeout* c_timeout, const STimeout* rw_timeout, const char* user_hdr, int/*bool*/ encode_args, ESwitch log){ static const char X_REQ_Q[] = "?"; static const char X_REQ_E[] = " HTTP/1.0\r\n"; static const char X_HOST[] = "Host: "; EIO_Status st; BUF buf; SOCK sock; char* header; char buffer[80]; size_t headersize; const char* x_args = 0; const char* x_req_r; /* "POST "/"GET " */ /* check the args */ if (!host || !*host || !port || !path || !*path || (user_hdr && *user_hdr && user_hdr[strlen(user_hdr)-1] != '\n')) { CORE_LOG(eLOG_Error, "[URL_Connect] Bad arguments"); assert(0); return 0/*error*/; } switch (req_method) { case eReqMethod_Any: x_req_r = DEF_CONN_REQ_METHOD " "; break; case eReqMethod_Post: x_req_r = "POST "; break; case eReqMethod_Get: x_req_r = "GET "; break; default: CORE_LOGF(eLOG_Error, ("[URL_Connect] Unrecognized request method" " (%d)", (int) req_method)); assert(0); return 0/*error*/; } if (content_length && strcasecmp(x_req_r, "GET ") == 0) { CORE_LOG(eLOG_Warning, "[URL_Connect] Content length ignored with GET"); content_length = 0; } /* URL-encode "args", if any specified */ if (args && *args) { size_t src_size = strlen(args); if ( encode_args ) { size_t dst_size = 3 * src_size; size_t src_read, dst_written; char* xx_args = (char*) malloc(dst_size + 1); if (!xx_args) return 0/*failure: no memory*/; URL_Encode(args, src_size, &src_read, xx_args, dst_size, &dst_written); xx_args[dst_written] = '\0'; assert(src_read == src_size); x_args = xx_args; } else x_args = args; } buf = 0; errno = 0; /* compose HTTP header */ if (/* {POST|GET} <path>?<args> HTTP/1.0\r\n */ !BUF_Write(&buf, x_req_r, strlen(x_req_r)) || !BUF_Write(&buf, path, strlen(path)) || (x_args && (!BUF_Write(&buf, X_REQ_Q, sizeof(X_REQ_Q) - 1) || !BUF_Write(&buf, x_args, strlen(x_args)))) || !BUF_Write(&buf, X_REQ_E, sizeof(X_REQ_E) - 1) || /* Host: host\r\n */ !BUF_Write(&buf, X_HOST, sizeof(X_HOST) - 1) || !BUF_Write(&buf, host, strlen(host)) || !BUF_Write(&buf, "\r\n", 2) || /* <user_header> */ (user_hdr && !BUF_Write(&buf, user_hdr, strlen(user_hdr))) || /* Content-Length: <content_length>\r\n\r\n */ (req_method != eReqMethod_Get && (sprintf(buffer, "Content-Length: %lu\r\n", (unsigned long) content_length) <= 0 || !BUF_Write(&buf, buffer, strlen(buffer)))) ||
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -