📄 ncbi_connutil.c
字号:
!BUF_Write(&buf, "\r\n", 2)) { CORE_LOGF(eLOG_Error, ("[URL_Connect] Error composing HTTP header for" " %s:%hu%s%s", host, port, errno ? ": " : "", errno ? strerror(errno) : "")); BUF_Destroy(buf); if (x_args && x_args != args) free((void*) x_args); return 0/*error*/; } if (x_args && x_args != args) free((void*) x_args); if (!(header = (char*) malloc(headersize = BUF_Size(buf))) || BUF_Read(buf, header, headersize) != headersize) { CORE_LOGF(eLOG_Error, ("[URL_Connect] Error storing HTTP header for" " %s:%hu: %s", host, port, errno ? strerror(errno) : "Unknown error")); if (header) free(header); BUF_Destroy(buf); return 0/*error*/; } BUF_Destroy(buf); /* connect to HTTPD */ st = SOCK_CreateEx(host, port, c_timeout, &sock, header, headersize, log); free(header); if (st != eIO_Success) { CORE_LOGF(eLOG_Error, ("[URL_Connect] Socket connect to %s:%hu failed: %s", host, port, IO_StatusStr(st))); return 0/*error*/; } /* setup I/O timeout for the connection */ if (SOCK_SetTimeout(sock, eIO_ReadWrite, rw_timeout) != eIO_Success) { CORE_LOG(eLOG_Error, "[URL_Connect] Cannot set connection timeout"); SOCK_Close(sock); return 0/*error*/; } /* success */ return sock;}/* Code for the "*_StripToPattern()" functions */typedef EIO_Status (*FDoIO) (void* stream, void* buf, size_t size, size_t* n_read, EIO_Event what /* eIO_Read | eIO_Write (to pushback) */ );static EIO_Status s_StripToPattern(void* stream, FDoIO io_func, const void* pattern, size_t pattern_size, BUF* buf, size_t* n_discarded){ EIO_Status status; char* buffer; size_t buffer_size; size_t n_read = 0; /* check args */ if ( n_discarded ) *n_discarded = 0; if (!stream || (pattern != 0) != (pattern_size != 0)) return eIO_InvalidArg; /* allocate a temporary read buffer */ buffer_size = 2 * pattern_size; if (buffer_size < 4096) buffer_size = 4096; if ( !(buffer = (char*) malloc(buffer_size)) ) return eIO_Unknown; if ( !pattern ) { /* read/discard until EOF */ do { status = io_func(stream, buffer, buffer_size, &n_read, eIO_Read); if ( buf ) BUF_Write(buf, buffer, n_read); if ( n_discarded ) *n_discarded += n_read; } while (status == eIO_Success); } else { for (;;) { /* read; search for the pattern; store the discarded data */ size_t x_read, n_stored; assert(n_read < pattern_size); status = io_func(stream, buffer + n_read, buffer_size - n_read, &x_read, eIO_Read); if ( !x_read ) { assert(status != eIO_Success); break; /*error*/ } n_stored = n_read + x_read; if (n_stored >= pattern_size) { /* search for the pattern */ size_t n_check = n_stored - pattern_size + 1; const char* b; for (b = buffer; n_check; b++, n_check--) { if (*b != *((const char*) pattern)) continue; if (memcmp(b, pattern, pattern_size) == 0) break; /*found*/ } /* pattern found */ if ( n_check ) { size_t x_discarded = (size_t)(b - buffer) + pattern_size; if ( buf ) BUF_Write(buf, buffer + n_read, x_discarded - n_read); if ( n_discarded ) *n_discarded += x_discarded; /* return unused portion to the stream */ status = io_func(stream, buffer + x_discarded, n_stored - x_discarded, 0, eIO_Write); break; /*finished*/ } } /* pattern not found yet */ if ( buf ) BUF_Write(buf, buffer + n_read, x_read); if ( n_discarded ) *n_discarded += x_read; n_read = n_stored; if (n_read > pattern_size) { size_t n_cut = n_read - pattern_size + 1; n_read = pattern_size - 1; memmove(buffer, buffer + n_cut, n_read); } } } /* cleanup & exit */ free(buffer); return status;}static EIO_Status s_CONN_IO(void* stream, void* buf, size_t size, size_t* n_read, EIO_Event what){ switch (what) { case eIO_Read: return CONN_Read((CONN) stream, buf, size, n_read, eIO_ReadPlain); case eIO_Write: assert(stream); return CONN_PushBack((CONN) stream, buf, size); default: break; } return eIO_InvalidArg;}extern EIO_Status CONN_StripToPattern(CONN conn, const void* pattern, size_t pattern_size, BUF* buf, size_t* n_discarded){ return s_StripToPattern (conn, s_CONN_IO, pattern, pattern_size, buf, n_discarded);}static EIO_Status s_SOCK_IO(void* stream, void* buf, size_t size, size_t* n_read, EIO_Event what){ switch (what) { case eIO_Read: return SOCK_Read((SOCK) stream, buf, size, n_read, eIO_ReadPlain); case eIO_Write: return SOCK_PushBack((SOCK) stream, buf, size); default: break; } return eIO_InvalidArg;}extern EIO_Status SOCK_StripToPattern(SOCK sock, const void* pattern, size_t pattern_size, BUF* buf, size_t* n_discarded){ return s_StripToPattern (sock, s_SOCK_IO, pattern, pattern_size, buf, n_discarded);}static EIO_Status s_BUF_IO(void* stream, void* buf, size_t size, size_t* n_read, EIO_Event what){ switch (what) { case eIO_Read: *n_read = BUF_Read((BUF) stream, buf, size); return *n_read ? eIO_Success : eIO_Closed; case eIO_Write: assert(stream); return BUF_PushBack((BUF*) &stream, buf, size) ? eIO_Success : eIO_Unknown; default: break; } return eIO_InvalidArg;}extern EIO_Status BUF_StripToPattern(BUF buffer, const void* pattern, size_t pattern_size, BUF* buf, size_t* n_discarded){ return s_StripToPattern (buffer, s_BUF_IO, pattern, pattern_size, buf, n_discarded);}/* Return integer (0..15) corresponding to the "ch" as a hex digit * Return -1 on error */static int s_HexChar(char ch){ if ('0' <= ch && ch <= '9') return ch - '0'; if ('a' <= ch && ch <= 'f') return 10 + (ch - 'a'); if ('A' <= ch && ch <= 'F') return 10 + (ch - 'A'); return -1;}/* The URL-encoding table */static const char s_Encode[256][4] = { "%00", "%01", "%02", "%03", "%04", "%05", "%06", "%07", "%08", "%09", "%0A", "%0B", "%0C", "%0D", "%0E", "%0F", "%10", "%11", "%12", "%13", "%14", "%15", "%16", "%17", "%18", "%19", "%1A", "%1B", "%1C", "%1D", "%1E", "%1F", "+", "!", "%22", "%23", "$", "%25", "%26", "'", "(", ")", "*", "%2B", ",", "-", ".", "%2F", "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "%3A", "%3B", "%3C", "%3D", "%3E", "%3F", "%40", "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z", "%5B", "%5C", "%5D", "%5E", "_", "%60", "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z", "%7B", "%7C", "%7D", "%7E", "%7F", "%80", "%81", "%82", "%83", "%84", "%85", "%86", "%87", "%88", "%89", "%8A", "%8B", "%8C", "%8D", "%8E", "%8F", "%90", "%91", "%92", "%93", "%94", "%95", "%96", "%97", "%98", "%99", "%9A", "%9B", "%9C", "%9D", "%9E", "%9F", "%A0", "%A1", "%A2", "%A3", "%A4", "%A5", "%A6", "%A7", "%A8", "%A9", "%AA", "%AB", "%AC", "%AD", "%AE", "%AF", "%B0", "%B1", "%B2", "%B3", "%B4", "%B5", "%B6", "%B7", "%B8", "%B9", "%BA", "%BB", "%BC", "%BD", "%BE", "%BF", "%C0", "%C1", "%C2", "%C3", "%C4", "%C5", "%C6", "%C7", "%C8", "%C9", "%CA", "%CB", "%CC", "%CD", "%CE", "%CF", "%D0", "%D1", "%D2", "%D3", "%D4", "%D5", "%D6", "%D7", "%D8", "%D9", "%DA", "%DB", "%DC", "%DD", "%DE", "%DF", "%E0", "%E1", "%E2", "%E3", "%E4", "%E5", "%E6", "%E7", "%E8", "%E9", "%EA", "%EB", "%EC", "%ED", "%EE", "%EF", "%F0", "%F1", "%F2", "%F3", "%F4", "%F5", "%F6", "%F7", "%F8", "%F9", "%FA", "%FB", "%FC", "%FD", "%FE", "%FF"};#define VALID_URL_SYMBOL(ch) (s_Encode[(unsigned char)ch][0] != '%')extern int/*bool*/ URL_DecodeEx(const void* src_buf, size_t src_size, size_t* src_read, void* dst_buf, size_t dst_size, size_t* dst_written, const char* allow_symbols){ unsigned char* src = (unsigned char*) src_buf; unsigned char* dst = (unsigned char*) dst_buf; *src_read = 0; *dst_written = 0; if (!src_size || !dst_size) return 1/*true*/; for ( ; *src_read != src_size && *dst_written != dst_size; (*src_read)++, (*dst_written)++, src++, dst++) { switch ( *src ) { case '%': { int i1, i2; if (*src_read + 2 > src_size) return 1/*true*/; if ((i1 = s_HexChar(*(++src))) == -1) return *dst_written ? 1/*true*/ : 0/*false*/; if (*src_read + 3 > src_size) return 1/*true*/; if ((i2 = s_HexChar(*(++src))) == -1) return *dst_written ? 1/*true*/ : 0/*false*/; *dst = (unsigned char)((i1 << 4) + i2); *src_read += 2; break; } case '+': { *dst = ' '; break; } default: { if (VALID_URL_SYMBOL(*src) || (allow_symbols && strchr(allow_symbols, *src))) *dst = *src; else return *dst_written ? 1/*true*/ : 0/*false*/; } }/*switch*/ } assert(src == (unsigned char*) src_buf + *src_read ); assert(dst == (unsigned char*) dst_buf + *dst_written); return 1/*true*/;}extern int/*bool*/ URL_Decode(const void* src_buf, size_t src_size, size_t* src_read, void* dst_buf, size_t dst_size, size_t* dst_written){ return URL_DecodeEx (src_buf, src_size, src_read, dst_buf, dst_size, dst_written, 0);}extern void URL_Encode(const void* src_buf, size_t src_size, size_t* src_read, void* dst_buf, size_t dst_size, size_t* dst_written){ unsigned char* src = (unsigned char*) src_buf; unsigned char* dst = (unsigned char*) dst_buf; *src_read = 0; *dst_written = 0; if (!src_size || !dst_size) return; for ( ; *src_read != src_size && *dst_written != dst_size; (*src_read)++, (*dst_written)++, src++, dst++) { const char* subst = s_Encode[*src]; if (*subst != '%') { *dst = *subst; } else if (*dst_written < dst_size - 2) { *dst = '%'; *(++dst) = *(++subst); *(++dst) = *(++subst); *dst_written += 2; } else { return; } } assert(src == (unsigned char*) src_buf + *src_read ); assert(dst == (unsigned char*) dst_buf + *dst_written);}/**************************************************************************** * NCBI-specific MIME content type and sub-types */static const char* s_MIME_Type[eMIME_T_Unknown+1] = { "x-ncbi-data", "text", "application", "unknown"};static const char* s_MIME_SubType[eMIME_Unknown+1] = { "x-dispatch", "x-asn-text", "x-asn-binary", "x-fasta", "x-www-form", "html", "plain", "xml", "xml+soap", "x-unknown"};static const char* s_MIME_Encoding[eENCOD_Unknown+1] = { "", "urlencoded", "encoded"};
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -