📄 common.c
字号:
if ((conn = _fetch_reopen(sd)) == NULL) { _fetch_syserr(); close(sd); } return (conn);}/* * Enable SSL on a connection. */RMint32_fetch_ssl(conn_t *conn, RMint32 verbose){#ifdef WITH_SSL /* Init the SSL library and context */ if (!SSL_library_init()){ fprintf(stderr, "SSL library init failed\n"); return (-1); } SSL_load_error_strings(); conn->ssl_meth = SSLv23_client_method(); conn->ssl_ctx = SSL_CTX_new(conn->ssl_meth); SSL_CTX_set_mode(conn->ssl_ctx, SSL_MODE_AUTO_RETRY); conn->ssl = SSL_new(conn->ssl_ctx); if (conn->ssl == NULL){ fprintf(stderr, "SSL context creation failed\n"); return (-1); } SSL_set_fd(conn->ssl, conn->sd); if (SSL_connect(conn->ssl) == -1){ ERR_print_errors_fp(stderr); return (-1); } if (verbose) { X509_NAME *name; RMascii *str; fprintf(stderr, "SSL connection established using %s\n", SSL_get_cipher(conn->ssl)); conn->ssl_cert = SSL_get_peer_certificate(conn->ssl); name = X509_get_subject_name(conn->ssl_cert); str = X509_NAME_oneline(name, 0, 0); printf("Certificate subject: %s\n", str); RMFree(str); name = X509_get_issuer_name(conn->ssl_cert); str = X509_NAME_oneline(name, 0, 0); printf("Certificate issuer: %s\n", str); RMFree(str); } return (0);#else (void)conn; (void)verbose; fprintf(stderr, "SSL support disabled\n"); return (-1);#endif}/* * Read a character from a connection w/ timeout */RMint32_fetch_read(conn_t *conn, RMuint8 *buf, RMuint32 len){ struct timeval now, timeout, wait; fd_set readfds; RMint32 rlen, total; RMint32 r; if (fetchTimeout) { FD_ZERO(&readfds); gettimeofday(&timeout, NULL); timeout.tv_sec += fetchTimeout; } //fprintf(stderr," [common] read %lu bytes\n", (RMuint32)len); total = 0; while (len > 0) { FD_ZERO(&readfds); while (fetchTimeout && !FD_ISSET(conn->sd, &readfds)) { FD_SET(conn->sd, &readfds); gettimeofday(&now, NULL); wait.tv_sec = timeout.tv_sec - now.tv_sec; wait.tv_usec = timeout.tv_usec - now.tv_usec; if (wait.tv_usec < 0) { wait.tv_usec += 1000000; wait.tv_sec--; } if (wait.tv_sec < 0) { errno = ETIMEDOUT; _fetch_syserr(); return (-1); } errno = 0; r = select(conn->sd + 1, &readfds, NULL, NULL, &wait); if (r == -1) { if (errno == EINTR && fetchRestartCalls) continue; _fetch_syserr(); return (-1); } }#ifdef WITH_SSL if (conn->ssl != NULL) rlen = SSL_read(conn->ssl, buf, len); else#endif rlen = read(conn->sd, buf, len); if (rlen == 0){ RMDBGLOG((HTTPDEBUG,"Error, short read: %s %ld/%ld\n", strerror(errno), total, total+len)); break; } if (rlen < 0) { if (errno == EINTR && fetchRestartCalls) continue; RMDBGLOG((HTTPDEBUG,"Error, reading read at %p: %s\n", buf, strerror(errno))); return (-1); } len -= rlen; buf += rlen; total += rlen; } return (total);}/* * Read a line of text from a connection w/ timeout */#define MIN_BUF_SIZE 1024RMint32_fetch_getln(conn_t *conn){ RMuint8 *tmp; RMuint32 tmpsize; RMint32 len; RMuint8 c; if (conn->buf == NULL) { if ((conn->buf = RMMalloc(MIN_BUF_SIZE)) == NULL) { errno = ENOMEM; return (-1); } conn->bufsize = MIN_BUF_SIZE; } conn->buf[0] = '\0'; conn->buflen = 0; do { len = _fetch_read(conn, &c, 1); if (len == -1){ RMDBGLOG((ENABLE,"len = -1 in _fetch_getln\n")); return (-1); } if (len == 0){ RMDBGLOG((ENABLE,"len = 0 in _fetch_getln\n")); break; } conn->buf[conn->buflen++] = c; if (conn->buflen == conn->bufsize) { tmp = conn->buf; tmpsize = conn->bufsize * 2 + 1; conn->buf = RMMalloc(tmpsize); if (conn->buf == NULL) { errno = ENOMEM; return (-1); } RMMemcpy(conn->buf, tmp, conn->bufsize); RMFree(tmp); conn->bufsize = tmpsize; } } while (c != '\n'); conn->buf[conn->buflen] = '\0'; RMDBGLOG((HTTPDEBUG, "<<< %s", conn->buf)); return (0);}/* * Write to a connection w/ timeout */RMint32_fetch_write(conn_t *conn, const RMuint8 *buf, RMuint32 len){ struct timeval now, timeout, wait; fd_set writefds; RMint32 wlen, total; RMint32 r; if (fetchTimeout) { FD_ZERO(&writefds); gettimeofday(&timeout, NULL); timeout.tv_sec += fetchTimeout; } //fprintf(stderr,"len = %d, timeout = %d\n", len, fetchTimeout); total = 0; while (len > 0) { while (fetchTimeout && !FD_ISSET(conn->sd, &writefds)) { FD_SET(conn->sd, &writefds); gettimeofday(&now, NULL); wait.tv_sec = timeout.tv_sec - now.tv_sec; wait.tv_usec = timeout.tv_usec - now.tv_usec; if (wait.tv_usec < 0) { wait.tv_usec += 1000000; wait.tv_sec--; } if (wait.tv_sec < 0) { errno = ETIMEDOUT; _fetch_syserr(); RMDBGLOG((ENABLE,"Error writing : %s\n", strerror(errno))); return (-1); } errno = 0; r = select(conn->sd + 1, NULL, &writefds, NULL, &wait); if (r == -1) { if (errno == EINTR && fetchRestartCalls) continue; RMDBGLOG((ENABLE,"Error writing : %s\n", strerror(errno))); return (-1); } }#ifdef WITH_SSL if (conn->ssl != NULL) wlen = SSL_write(conn->ssl, buf, len); else#endif //fprintf(stderr,"before len = %d, conn = %p, sd = %d\n", len, conn, conn->sd); wlen = write(conn->sd, buf, len); //fprintf(stderr,"wlen = %d\n", wlen); if (wlen == 0) { /* we consider a short write a failure */ errno = EPIPE; _fetch_syserr(); RMDBGLOG((HTTPDEBUG,"Error writing : %s\n", strerror(errno))); return (-1); } if (wlen < 0) { if (errno == EINTR && fetchRestartCalls) continue; RMDBGLOG((HTTPDEBUG,"Error writing : %s\n", strerror(errno))); return (-1); } len -= wlen; buf += wlen; total += wlen; } return (total);}#define CONCAT_BUFFER_SIZE 2048/* * Write a line of text to a connection w/ timeout */RMint32_fetch_putln(conn_t *conn, const RMascii *str, RMuint32 len){ static RMuint8 concatBuffer[CONCAT_BUFFER_SIZE]; static RMuint32 concatLength = 0; RMint32 status; RMDBGLOG((HTTPDEBUG,">>> %s (%ld)\n", str, (RMuint32) len)); /* If the end of the message, ... */ if (len == 0) { /* Concatenate the final \r\n to the end of the message */ sprintf((char*)&concatBuffer[concatLength], "%s", ENDL); /* Send the message over TCP/IP */ SAFE(_fetch_write(conn, concatBuffer, concatLength + 2)); /* Reset to the beginning of the concatenation buffer */ concatLength = 0; /* Finished, so return immediately */ return (0); } /* If the line will not fit in the concatenation buffer, ... */ if (concatLength + len + 4 >= CONCAT_BUFFER_SIZE) { /* Flush the current contents of the concatenation buffer over TCP/IP */ if (concatLength > 0) SAFE(_fetch_write(conn, concatBuffer, concatLength)); /* Reset to the beginning of the concatenation buffer */ concatLength = 0; } /* If the line still will not fit in the concatenation buffer, ... */ if (concatLength + len + 4 >= CONCAT_BUFFER_SIZE) { /* Send the line directly (bypass the concatenation buffer) */ SAFE(_fetch_write(conn, (RMuint8 *)str, len)); /* Concatenate a \r\n to the concatenation buffer to mark the end of that line */ sprintf((char*)&concatBuffer[concatLength], "%s", ENDL); concatLength += 2; } else { /* It is safe to concatenate the current line into the concatenation buffer */ sprintf((char*)&concatBuffer[concatLength], "%s%s", str, ENDL); concatLength += (len + 2); } return (0);}/* * Close connection */RMint32_fetch_close(conn_t *conn){ RMint32 ret; if (--conn->ref > 0) return (0); ret = close(conn->sd); if (conn->buf) RMFree(conn->buf); RMFree(conn); return (ret);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -