📄 conn.c
字号:
int rc; rc = SocketWait(connectionP->socketP, TRUE, FALSE, timeLeft * 1000); if (rc != 1) cantGetData = TRUE; else { uint32_t bytesAvail; bytesAvail = SocketAvailableReadBytes(connectionP->socketP); if (bytesAvail <= 0) cantGetData = TRUE; else { uint32_t const bytesToRead = MIN(bytesAvail, bufferSpace(connectionP)-1); uint32_t bytesRead; bytesRead = SocketRead( connectionP->socketP, connectionP->buffer + connectionP->buffersize, bytesToRead); if (bytesRead > 0) { traceSocketRead(connectionP, bytesRead); connectionP->inbytes += bytesRead; connectionP->buffersize += bytesRead; connectionP->buffer[connectionP->buffersize] = '\0'; gotData = TRUE; } } } } } if (gotData) return TRUE; else return FALSE;} abyss_boolConnWrite(TConn * const connectionP, const void * const buffer, uint32_t const size) { abyss_bool failed; SocketWrite(connectionP->socketP, buffer, size, &failed); traceSocketWrite(connectionP, buffer, size, failed); if (!failed) connectionP->outbytes += size; return !failed;}abyss_boolConnWriteFromFile(TConn * const connectionP, TFile * const fileP, uint64_t const start, uint64_t const last, void * const buffer, uint32_t const buffersize, uint32_t const rate) {/*---------------------------------------------------------------------------- Write the contents of the file stream *fileP, from offset 'start' up through 'last', to the HTTP connection *connectionP. Meter the reading so as not to read more than 'rate' bytes per second. Use the 'bufferSize' bytes at 'buffer' as an internal buffer for this.-----------------------------------------------------------------------------*/ abyss_bool retval; uint32_t waittime; abyss_bool success; uint32_t readChunkSize; if (rate > 0) { readChunkSize = MIN(buffersize, rate); /* One second's worth */ waittime = (1000 * buffersize) / rate; } else { readChunkSize = buffersize; waittime = 0; } success = FileSeek(fileP, start, SEEK_SET); if (!success) retval = FALSE; else { uint64_t const totalBytesToRead = last - start + 1; uint64_t bytesread; bytesread = 0; /* initial value */ while (bytesread < totalBytesToRead) { uint64_t const bytesLeft = totalBytesToRead - bytesread; uint64_t const bytesToRead = MIN(readChunkSize, bytesLeft); uint64_t bytesReadThisTime; bytesReadThisTime = FileRead(fileP, buffer, bytesToRead); bytesread += bytesReadThisTime; if (bytesReadThisTime > 0) ConnWrite(connectionP, buffer, bytesReadThisTime); else break; if (waittime > 0) xmlrpc_millisecond_sleep(waittime); } retval = (bytesread >= totalBytesToRead); } return retval;}static voidprocessHeaderLine(char * const start, const char * const headerStart, TConn * const connectionP, time_t const deadline, abyss_bool * const gotHeaderP, char ** const nextP, abyss_bool * const errorP) {/*---------------------------------------------------------------------------- If there's enough data in the buffer at *pP, process a line of HTTP header. It is part of a header that starts at 'headerStart' and has been previously processed up to 'start'. The data in the buffer is terminated by a NUL. WE MODIFY THE DATA.-----------------------------------------------------------------------------*/ abyss_bool gotHeader; char * lfPos; char * p; p = start; gotHeader = FALSE; /* initial assumption */ lfPos = strchr(p, LF); if (lfPos) { if ((*p != LF) && (*p != CR)) { /* We're looking at a non-empty line */ if (*(lfPos+1) == '\0') { /* There's nothing in the buffer after the line, so we don't know if there's a continuation line coming. Must read more. */ int const timeLeft = deadline - time(NULL); *errorP = !ConnRead(connectionP, timeLeft); } if (!*errorP) { p = lfPos; /* Point to LF */ /* If the next line starts with whitespace, it's a continuation line, so blank out the line delimiter (LF or CRLF) so as to join the next line with this one. */ if ((*(p+1) == ' ') || (*(p+1) == '\t')) { if (p > headerStart && *(p-1) == CR) *(p-1) = ' '; *p++ = ' '; } else gotHeader = TRUE; } } else { /* We're looking at an empty line (i.e. what marks the end of the header) */ p = lfPos; /* Point to LF */ gotHeader = TRUE; } } if (gotHeader) { /* 'p' points to the final LF */ /* Replace the LF or the CR in CRLF with NUL, so as to terminate the string at 'headerStart' that is the full header. */ if (p > headerStart && *(p-1) == CR) *(p-1) = '\0'; /* NUL out CR in CRLF */ else *p = '\0'; /* NUL out LF */ ++p; /* Point to next line in buffer */ } *gotHeaderP = gotHeader; *nextP = p;}abyss_boolConnReadHeader(TConn * const connectionP, char ** const headerP) {/*---------------------------------------------------------------------------- Read an HTTP header on connection *connectionP. An HTTP header is basically a line, except that if a line starts with white space, it's a continuation of the previous line. A line is delimited by either LF or CRLF. In the course of reading, we read at least one character past the line delimiter at the end of the header; we may read much more. We leave everything after the header (and its line delimiter) in the internal buffer, with the buffer pointer pointing to it. We use stuff already in the internal buffer (perhaps left by a previous call to this subroutine) before reading any more from from the socket. Return as *headerP the header value. This is in the connection's internal buffer. This contains no line delimiters.-----------------------------------------------------------------------------*/ uint32_t const deadline = time(NULL) + connectionP->server->srvP->timeout; abyss_bool retval; char * p; char * headerStart; abyss_bool error; abyss_bool gotHeader; p = connectionP->buffer + connectionP->bufferpos; headerStart = p; gotHeader = FALSE; error = FALSE; while (!gotHeader && !error) { int const timeLeft = deadline - time(NULL); if (timeLeft <= 0) error = TRUE; else { if (p >= connectionP->buffer + connectionP->buffersize) /* Need more data from the socket to chew on */ error = !ConnRead(connectionP, timeLeft); if (!error) { assert(connectionP->buffer + connectionP->buffersize > p); processHeaderLine(p, headerStart, connectionP, deadline, &gotHeader, &p, &error); } } } if (gotHeader) { /* We've consumed this part of the buffer (but be careful -- you can't reuse that part of the buffer because the string we're returning is in it! */ connectionP->bufferpos += p - headerStart; *headerP = headerStart; retval = TRUE; } else retval = FALSE; return retval;}TServer *ConnServer(TConn * const connectionP) { return connectionP->server;}/*********************************************************************************** conn.c**** This file is part of the ABYSS Web server project.**** Copyright (C) 2000 by Moez Mahfoudh <mmoez@bigfoot.com>.** All rights reserved.**** Redistribution and use in source and binary forms, with or without** modification, are permitted provided that the following conditions** are met:** 1. Redistributions of source code must retain the above copyright** notice, this list of conditions and the following disclaimer.** 2. Redistributions in binary form must reproduce the above copyright** notice, this list of conditions and the following disclaimer in the** documentation and/or other materials provided with the distribution.** 3. The name of the author may not be used to endorse or promote products** derived from this software without specific prior written permission.** ** THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE** ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE** FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL** DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS** OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)** HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY** OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF** SUCH DAMAGE.********************************************************************************/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -