📄 http.c
字号:
response->status_message = strdup (status_message); if (response->status_message == NULL) { free (response); return NULL; } return response;}Http_response *http_create_response (int major_version, int minor_version, int status_code, const char *status_message){ Http_response *response; response = http_allocate_response (status_message); if (response == NULL) return NULL; response->major_version = major_version; response->minor_version = minor_version; response->status_code = status_code; response->header = NULL; return response;}ssize_thttp_parse_response (int fd, Http_response **response_){ Http_response *response; unsigned char *data; size_t len; ssize_t n; *response_ = NULL; response = malloc (sizeof (Http_response)); if (response == NULL) { log_error ("http_parse_response: out of memory"); return -1; } response->major_version = -1; response->minor_version = -1; response->status_code = -1; response->status_message = NULL; response->header = NULL; n = read_until (fd, '/', &data); if (n <= 0) { free (response); return n; } else if (n != 5 || memcmp (data, "HTTP", 4) != 0) { log_error ("http_parse_response: expected \"HTTP\""); free (data); free (response); return -1; } free (data); len = n; n = read_until (fd, '.', &data); if (n <= 0) { free (response); return n; } data[n - 1] = 0; response->major_version = atoi (data); log_verbose ("http_parse_response: major version = %d", response->major_version); free (data); len += n; n = read_until (fd, ' ', &data); if (n <= 0) { free (response); return n; } data[n - 1] = 0; response->minor_version = atoi (data); log_verbose ("http_parse_response: minor version = %d", response->minor_version); free (data); len += n; n = read_until (fd, ' ', &data); if (n <= 0) { free (response); return n; } data[n - 1] = 0; response->status_code = atoi (data); log_verbose ("http_parse_response: status code = %d", response->status_code); free (data); len += n; n = read_until (fd, '\r', &data); if (n <= 0) { free (response); return n; } data[n - 1] = 0; response->status_message = data; log_verbose ("http_parse_response: status message = \"%s\"", response->status_message); len += n; n = read_until (fd, '\n', &data); if (n <= 0) { http_destroy_response (response); return n; } free (data); if (n != 1) { log_error ("http_parse_request: invalid line ending"); http_destroy_response (response); return -1; } len += n; n = parse_header (fd, &response->header); if (n <= 0) { http_destroy_response (response); return n; } len += n; *response_ = response; return len;}voidhttp_destroy_response (Http_response *response){ if (response->status_message) free ((char *)response->status_message); http_destroy_header (response->header); free (response);}static inline Http_request *http_allocate_request (const char *uri){ Http_request *request; request = malloc (sizeof (Http_request)); if (request == NULL) return NULL; request->uri = strdup (uri); if (request->uri == NULL) { free (request); return NULL; } return request;}Http_request *http_create_request (Http_method method, const char *uri, int major_version, int minor_version){ Http_request *request; request = http_allocate_request (uri); if (request == NULL) return NULL; request->method = method; request->major_version = major_version; request->minor_version = minor_version; request->header = NULL; return request;}ssize_thttp_parse_request (int fd, Http_request **request_){ Http_request *request; unsigned char *data; size_t len; ssize_t n; *request_ = NULL; request = malloc (sizeof (Http_request)); if (request == NULL) { log_error ("http_parse_request: out of memory"); return -1; } request->method = -1; request->uri = NULL; request->major_version = -1; request->minor_version = -1; request->header = NULL; n = read_until (fd, ' ', &data); if (n <= 0) { free (request); return n; } request->method = http_string_to_method (data, n - 1); if (request->method == -1) { log_error ("http_parse_request: expected an HTTP method"); free (data); free (request); return -1; } data[n - 1] = 0; log_verbose ("http_parse_request: method = \"%s\"", data); free (data); len = n; n = read_until (fd, ' ', &data); if (n <= 0) { free (request); return n; } data[n - 1] = 0; request->uri = data; len += n; log_verbose ("http_parse_request: uri = \"%s\"", request->uri); n = read_until (fd, '/', &data); if (n <= 0) { http_destroy_request (request); return n; } else if (n != 5 || memcmp (data, "HTTP", 4) != 0) { log_error ("http_parse_request: expected \"HTTP\""); free (data); http_destroy_request (request); return -1; } free (data); len = n; n = read_until (fd, '.', &data); if (n <= 0) { http_destroy_request (request); return n; } data[n - 1] = 0; request->major_version = atoi (data); log_verbose ("http_parse_request: major version = %d", request->major_version); free (data); len += n; n = read_until (fd, '\r', &data); if (n <= 0) { http_destroy_request (request); return n; } data[n - 1] = 0; request->minor_version = atoi (data); log_verbose ("http_parse_request: minor version = %d", request->minor_version); free (data); len += n; n = read_until (fd, '\n', &data); if (n <= 0) { http_destroy_request (request); return n; } free (data); if (n != 1) { log_error ("http_parse_request: invalid line ending"); http_destroy_request (request); return -1; } len += n; n = parse_header (fd, &request->header); if (n <= 0) { http_destroy_request (request); return n; } len += n; *request_ = request; return len;}ssize_thttp_write_request (int fd, Http_request *request){ char str[1024]; /* FIXME: buffer overflow */ ssize_t n = 0; size_t m; m = sprintf (str, "%s %s HTTP/%d.%d\r\n", http_method_to_string (request->method), request->uri, request->major_version, request->minor_version); m = write_all (fd, str, m); log_verbose ("http_write_request: %s", str); if (m == -1) { log_error ("http_write_request: write error: %s", strerror (errno)); return -1; } n += m; m = http_write_header (fd, request->header); if (m == -1) { return -1; } n += m; return n;}voidhttp_destroy_request (Http_request *request){ if (request->uri) free ((char *)request->uri); http_destroy_header (request->header); free (request);}static Http_header *http_header_find (Http_header *header, const char *name){ if (header == NULL) return NULL; if (strcmp (header->name, name) == 0) return header; return http_header_find (header->next, name);}const char *http_header_get (Http_header *header, const char *name){ Http_header *h; h = http_header_find (header, name); if (h == NULL) return NULL; return h->value;}#if 0voidhttp_header_set (Http_header **header, const char *name, const char *value){ Http_header *h; size_t n; char *v; n = strlen (value); v = malloc (n + 1); if (v == NULL) fail; memcpy (v, value, n + 1); h = http_header_find (*header, name); if (h == NULL) { Http_header *h2; h2 = malloc (sizeof (Http_header)); if (h2 == NULL) fail; n = strlen (name); h2->name = malloc (strlen (name) + 1); if (h2->name == NULL) fail; memcpy (h2->name, name, n + 1); h2->value = v; h2->next = *header; *header = h2; return NULL; } else { free (h->value); h->value = v; }}#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -