📄 http.c
字号:
{ /* * Skip leading whitespace... */ while (isspace(*fptr & 255)) fptr ++; if (*fptr == ',') { fptr ++; continue; } /* * Get the sub-field name... */ for (ptr = temp; *fptr && *fptr != '=' && !isspace(*fptr & 255) && ptr < (temp + sizeof(temp) - 1); *ptr++ = *fptr++); *ptr = '\0'; DEBUG_printf(("httpGetSubField: name=\"%s\"\n", temp)); /* * Skip trailing chars up to the '='... */ while (isspace(*fptr & 255)) fptr ++; if (!*fptr) break; if (*fptr != '=') continue; /* * Skip = and leading whitespace... */ fptr ++; while (isspace(*fptr & 255)) fptr ++; if (*fptr == '\"') { /* * Read quoted string... */ for (ptr = value, fptr ++; *fptr && *fptr != '\"' && ptr < (value + HTTP_MAX_VALUE - 1); *ptr++ = *fptr++); *ptr = '\0'; while (*fptr && *fptr != '\"') fptr ++; if (*fptr) fptr ++; } else { /* * Read unquoted string... */ for (ptr = value; *fptr && !isspace(*fptr & 255) && *fptr != ',' && ptr < (value + HTTP_MAX_VALUE - 1); *ptr++ = *fptr++); *ptr = '\0'; while (*fptr && !isspace(*fptr & 255) && *fptr != ',') fptr ++; } DEBUG_printf(("httpGetSubField: value=\"%s\"\n", value)); /* * See if this is the one... */ if (strcmp(name, temp) == 0) return (value); } value[0] = '\0'; return (NULL);}/* * 'httpSetField()' - Set the value of an HTTP header. */voidhttpSetField(http_t *http, /* I - HTTP data */ http_field_t field, /* I - Field index */ const char *value) /* I - Value */{ if (http == NULL || field < HTTP_FIELD_ACCEPT_LANGUAGE || field > HTTP_FIELD_WWW_AUTHENTICATE || value == NULL) return; strlcpy(http->fields[field], value, HTTP_MAX_VALUE);}/* * 'httpDelete()' - Send a DELETE request to the server. */int /* O - Status of call (0 = success) */httpDelete(http_t *http, /* I - HTTP data */ const char *uri) /* I - URI to delete */{ return (http_send(http, HTTP_DELETE, uri));}/* * 'httpGet()' - Send a GET request to the server. */int /* O - Status of call (0 = success) */httpGet(http_t *http, /* I - HTTP data */ const char *uri) /* I - URI to get */{ return (http_send(http, HTTP_GET, uri));}/* * 'httpHead()' - Send a HEAD request to the server. */int /* O - Status of call (0 = success) */httpHead(http_t *http, /* I - HTTP data */ const char *uri) /* I - URI for head */{ return (http_send(http, HTTP_HEAD, uri));}/* * 'httpOptions()' - Send an OPTIONS request to the server. */int /* O - Status of call (0 = success) */httpOptions(http_t *http, /* I - HTTP data */ const char *uri) /* I - URI for options */{ return (http_send(http, HTTP_OPTIONS, uri));}/* * 'httpPost()' - Send a POST request to the server. */int /* O - Status of call (0 = success) */httpPost(http_t *http, /* I - HTTP data */ const char *uri) /* I - URI for post */{ httpGetLength(http); return (http_send(http, HTTP_POST, uri));}/* * 'httpPut()' - Send a PUT request to the server. */int /* O - Status of call (0 = success) */httpPut(http_t *http, /* I - HTTP data */ const char *uri) /* I - URI to put */{ httpGetLength(http); return (http_send(http, HTTP_PUT, uri));}/* * 'httpTrace()' - Send an TRACE request to the server. */int /* O - Status of call (0 = success) */httpTrace(http_t *http, /* I - HTTP data */ const char *uri) /* I - URI for trace */{ return (http_send(http, HTTP_TRACE, uri));}/* * 'httpFlush()' - Flush data from a HTTP connection. */voidhttpFlush(http_t *http) /* I - HTTP data */{ char buffer[8192]; /* Junk buffer */ DEBUG_printf(("httpFlush(http=%p), state=%d\n", http, http->state)); while (httpRead(http, buffer, sizeof(buffer)) > 0);}/* * 'httpRead()' - Read data from a HTTP connection. */int /* O - Number of bytes read */httpRead(http_t *http, /* I - HTTP data */ char *buffer, /* I - Buffer for data */ int length) /* I - Maximum number of bytes */{ int bytes; /* Bytes read */ char len[32]; /* Length string */ DEBUG_printf(("httpRead(http=%p, buffer=%p, length=%d)\n", http, buffer, length)); if (http == NULL || buffer == NULL) return (-1); http->activity = time(NULL); if (length <= 0) return (0); if (http->data_encoding == HTTP_ENCODE_CHUNKED && http->data_remaining <= 0) { DEBUG_puts("httpRead: Getting chunk length..."); if (httpGets(len, sizeof(len), http) == NULL) { DEBUG_puts("httpRead: Could not get length!"); return (0); } http->data_remaining = strtol(len, NULL, 16); if (http->data_remaining < 0) { DEBUG_puts("httpRead: Negative chunk length!"); return (0); } } DEBUG_printf(("httpRead: data_remaining=%d\n", http->data_remaining)); if (http->data_remaining <= 0) { /* * A zero-length chunk ends a transfer; unless we are reading POST * data, go idle... */ if (http->data_encoding == HTTP_ENCODE_CHUNKED) httpGets(len, sizeof(len), http); if (http->state == HTTP_POST_RECV) http->state ++; else http->state = HTTP_WAITING; /* * Prevent future reads for this request... */ http->data_encoding = HTTP_ENCODE_LENGTH; return (0); } else if (length > http->data_remaining) length = http->data_remaining; if (http->used == 0 && length <= 256) { /* * Buffer small reads for better performance... */ if (!http->blocking && !httpWait(http, 1000)) return (0); if (http->data_remaining > sizeof(http->buffer)) bytes = sizeof(http->buffer); else bytes = http->data_remaining;#ifdef HAVE_SSL if (http->tls) bytes = http_read_ssl(http, http->buffer, bytes); else#endif /* HAVE_SSL */ { DEBUG_printf(("httpRead: reading %d bytes from socket into buffer...\n", bytes)); bytes = recv(http->fd, http->buffer, bytes, 0); DEBUG_printf(("httpRead: read %d bytes from socket into buffer...\n", bytes)); } if (bytes > 0) http->used = bytes; else if (bytes < 0) {#ifdef WIN32 http->error = WSAGetLastError(); return (-1);#else if (errno != EINTR) { http->error = errno; return (-1); }#endif /* WIN32 */ } else { http->error = EPIPE; return (0); } } if (http->used > 0) { if (length > http->used) length = http->used; bytes = length; DEBUG_printf(("httpRead: grabbing %d bytes from input buffer...\n", bytes)); memcpy(buffer, http->buffer, length); http->used -= length; if (http->used > 0) memmove(http->buffer, http->buffer + length, http->used); }#ifdef HAVE_SSL else if (http->tls) { if (!http->blocking && !httpWait(http, 1000)) return (0); bytes = http_read_ssl(http, buffer, length); }#endif /* HAVE_SSL */ else { if (!http->blocking && !httpWait(http, 1000)) return (0); DEBUG_printf(("httpRead: reading %d bytes from socket...\n", length)); bytes = recv(http->fd, buffer, length, 0); DEBUG_printf(("httpRead: read %d bytes from socket...\n", bytes)); } if (bytes > 0) http->data_remaining -= bytes; else if (bytes < 0) {#ifdef WIN32 http->error = WSAGetLastError();#else if (errno == EINTR) bytes = 0; else http->error = errno;#endif /* WIN32 */ } else { http->error = EPIPE; return (0); } if (http->data_remaining == 0) { if (http->data_encoding == HTTP_ENCODE_CHUNKED) httpGets(len, sizeof(len), http); if (http->data_encoding != HTTP_ENCODE_CHUNKED) { if (http->state == HTTP_POST_RECV) http->state ++; else http->state = HTTP_WAITING; } }#ifdef DEBUG { int i, j, ch; printf("httpRead: Read %d bytes:\n", bytes); for (i = 0; i < bytes; i += 16) { printf(" "); for (j = 0; j < 16 && (i + j) < bytes; j ++) printf(" %02X", buffer[i + j] & 255); while (j < 16) { printf(" "); j ++; } printf(" "); for (j = 0; j < 16 && (i + j) < bytes; j ++) { ch = buffer[i + j] & 255; if (ch < ' ' || ch == 127) ch = '.'; putchar(ch); } putchar('\n'); } }#endif /* DEBUG */ return (bytes);}/* * 'httpSetCookie()' - Set the cookie value(s)... */voidhttpSetCookie(http_t *http, /* I - Connection */ const char *cookie) /* I - Cookie string */{ if (!http) return; if (http->cookie) free(http->cookie); if (cookie) http->cookie = strdup(cookie); else http->cookie = NULL;}/* * 'httpWait()' - Wait for data available on a connection. */int /* O - 1 if data is available, 0 otherwise */httpWait(http_t *http, /* I - HTTP data */ int msec) /* I - Milliseconds to wait */{ /* * First see if there is data in the buffer... */ if (http == NULL) return (0); if (http->used) return (1); /* * If not, check the SSL/TLS buffers and do a select() on the connection... */ return (http_wait(http, msec));}/* * 'httpWrite()' - Write data to a HTTP connection. */ int /* O - Number of bytes written */httpWrite(http_t *http, /* I - HTTP data */ const char *buffer, /* I - Buffer for data */ int length) /* I - Number of bytes to write */{ int tbytes, /* Total bytes sent */ bytes; /* Bytes sent */ if (http == NULL || buffer == NULL) return (-1); http->activity = time(NULL); if (http->data_encoding == HTTP_ENCODE_CHUNKED) { if (httpPrintf(http, "%x\r\n", length) < 0) return (-1); if (length == 0) { /* * A zero-length chunk ends a transfer; unless we are sending POST * or PUT data, go idle... */ DEBUG_puts("httpWrite: changing states..."); if (http->state == HTTP_POST_RECV) http->state ++; else if (http->state == HTTP_PUT_RECV) http->state = HTTP_STATUS; else http->state = HTTP_WAITING; if (httpPrintf(http, "\r\n") < 0) return (-1); return (0); } } tbytes = 0; while (length > 0) {#ifdef HAVE_SSL if (http->tls) bytes = http_write_ssl(http, buffer, length); else#endif /* HAVE_SSL */ bytes = send(http->fd, buffer, length, 0); if (bytes < 0) {#ifdef WIN32 if (WSAGetLastError() != http->error) { http->error = WSAGetLastError(); continue; }#else if (errno == EINTR) continue; else if (errno != http->error && errno != ECONNRESET) { http->error = errno; continue; }#endif /* WIN32 */ DEBUG_puts("httpWrite: error writing data...\n"); return (-1); } buffer += bytes; tbytes += bytes; length -= bytes; if (http->data_encoding == HTTP_ENCODE_LENGTH) http->data_remaining -= bytes; } if (http->data_encoding == HTTP_ENCODE_CHUNKED) if (httpPrintf(http, "\r\n") < 0) return (-1); if (http->data_remaining == 0 && http->data_encoding == HTTP_ENCODE_LENGTH) { /* * Finished with the transfer; unless we are sending POST or PUT * data, go idle... */ DEBUG_puts("httpWrite: changing states..."); if (http->state == HTTP_POST_RECV) http->state ++; else if (http->state == HTTP_PUT_RECV) http->state = HTTP_STATUS; else http->state = HTTP_WAITING; }#ifdef DEBUG { int i, j, ch; printf("httpWrite: wrote %d bytes: \n", tbytes); for (i = 0, buffer -= tbytes; i < tbytes; i += 16) { printf(" "); for (j = 0; j < 16 && (i + j) < tbytes; j ++) printf(" %02X", buffer[i + j] & 255); while (j < 16) { printf(" "); j ++; } printf(" "); for (j = 0; j < 16 && (i + j) < tbytes; j ++) { ch = buffer[i + j] & 255; if (ch < ' ' || ch == 127) ch = '.'; putchar(ch); } putchar('\n'); } }#endif /* DEBUG */ return (tbytes);}/* * 'httpGets()' - Get a line of text from a HTTP connection. */char * /* O - Line or NULL */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -