Home | History | Annotate | Download | only in mongoose

Lines Matching full:conn

484 static void *call_user(struct mg_connection *conn, enum mg_event event) {
485 conn->request_info.user_data = conn->ctx->user_data;
486 return conn->ctx->user_callback == NULL ? NULL :
487 conn->ctx->user_callback(event, conn, &conn->request_info);
514 static void cry(struct mg_connection *conn, const char *fmt, ...) {
527 conn->request_info.log_message = buf;
528 if (call_user(conn, MG_EVENT_LOG) == NULL) {
529 fp = conn->ctx->config[ERROR_LOG_FILE] == NULL ? NULL :
530 mg_fopen(conn->ctx->config[ERROR_LOG_FILE], "a+");
539 inet_ntoa(conn->client.rsa.u.sin.sin_addr));
541 if (conn->request_info.request_method != NULL) {
543 conn->request_info.request_method,
544 conn->request_info.uri);
555 conn->request_info.log_message = NULL;
627 static int mg_vsnprintf(struct mg_connection *conn, char *buf, size_t buflen,
637 cry(conn, "vsnprintf error");
640 cry(conn, "truncating vsnprintf buffer: [%.*s]",
649 static int mg_snprintf(struct mg_connection *conn, char *buf, size_t buflen,
655 n = mg_vsnprintf(conn, buf, buflen, fmt, ap);
725 const char *mg_get_header(const struct mg_connection *conn, const char *name) {
726 return get_header(&conn->request_info, name);
786 static int should_keep_alive(const struct mg_connection *conn) {
787 const char *http_version = conn->request_info.http_version;
788 const char *header = mg_get_header(conn, "Connection");
793 static const char *suggest_connection_header(const struct mg_connection *conn) {
794 return should_keep_alive(conn) ? "keep-alive" : "close";
797 static void send_http_error(struct mg_connection *conn, int status,
803 conn->request_info.status_code = status;
805 if (call_user(conn, MG_HTTP_ERROR) == NULL) {
811 len = mg_snprintf(conn, buf, sizeof(buf), "Error %d: %s", status, reason);
812 cry(conn, "%s", buf);
816 len += mg_vsnprintf(conn, buf + len, sizeof(buf) - len, fmt, ap);
821 mg_printf(conn, "HTTP/1.1 %d %s\r\n"
825 suggest_connection_header(conn));
826 conn->num_bytes_sent += mg_printf(conn, "%s", buf);
1135 static pid_t spawn_process(struct mg_connection *conn, const char *prog,
1161 interp = conn->ctx->config[CGI_INTERPRETER];
1164 mg_snprintf(conn, cmdline, sizeof(cmdline), "%s%c%s", dir, DIRSEP, prog);
1181 (void) mg_snprintf(conn, cmdline, sizeof(cmdline), "%s%s%s%c%s",
1187 cry(conn, "%s: CreateProcess(%s): %d",
1248 static pid_t spawn_process(struct mg_connection *conn, const char *prog,
1258 send_http_error(conn, 500, http_500_error, "fork(): %s", strerror(ERRNO));
1262 cry(conn, "%s: chdir(%s): %s", __func__, dir, strerror(ERRNO));
1264 cry(conn, "%s: dup2(%d, 0): %s", __func__, fd_stdin, strerror(ERRNO));
1266 cry(conn, "%s: dup2(%d, 1): %s", __func__, fd_stdout, strerror(ERRNO));
1273 interp = conn->ctx->config[CGI_INTERPRETER];
1276 cry(conn, "%s: execle(%s): %s", __func__, prog, strerror(ERRNO));
1279 cry(conn, "%s: execle(%s %s): %s", __func__, interp, prog,
1357 int mg_read(struct mg_connection *conn, void *buf, size_t len) {
1361 assert((conn->content_len == -1 && conn->consumed_content == 0) ||
1362 conn->consumed_content <= conn->content_len);
1364 conn->content_len, conn->consumed_content));
1366 if (conn->consumed_content < conn->content_len) {
1369 int64_t to_read = conn->content_len - conn->consumed_content;
1375 buffered = conn->buf + conn->request_len + conn->consumed_content;
1376 buffered_len = conn->data_len - conn->request_len;
1380 if (conn->consumed_content < (int64_t) buffered_len) {
1381 buffered_len -= (int) conn->consumed_content;
1388 conn->consumed_content += buffered_len;
1394 n = pull(NULL, conn->client.sock, conn->ssl, (char *) buf, (int) len);
1399 conn->consumed_content += n;
1407 int mg_write(struct mg_connection *conn, const void *buf, size_t len) {
1408 return (int) push(NULL, conn->client.sock, conn->ssl,
1412 int mg_printf(struct mg_connection *conn, const char *fmt, ...) {
1418 len = mg_vsnprintf(conn, buf, sizeof(buf), fmt, ap);
1421 return mg_write(conn, buf, (size_t)len);
1495 int mg_get_cookie(const struct mg_connection *conn, const char *cookie_name,
1501 if ((s = mg_get_header(conn, "Cookie")) == NULL) {
1532 static int get_document_root(const struct mg_connection *conn,
1538 uri = conn->request_info.uri;
1540 root = next_option(conn->ctx->config[DOCUMENT_ROOT], document_root, NULL);
1553 static void convert_uri_to_file_name(struct mg_connection *conn,
1559 match_len = get_document_root(conn, &vec);
1560 mg_snprintf(conn, buf, buf_len, "%.*s%s", vec.len, vec.ptr, uri + match_len);
1569 static int sslize(struct mg_connection *conn, int (*func)(SSL *)) {
1570 return (conn->ssl = SSL_new(conn->ctx->ssl_ctx)) != NULL &&
1571 SSL_set_fd(conn->ssl, conn->client.sock) == 1 &&
1572 func(conn->ssl) == 1;
1575 static struct mg_connection *mg_connect(struct mg_connection *conn,
1582 if (conn->ctx->ssl_ctx == NULL && use_ssl) {
1583 cry(conn, "%s: SSL is not initialized", __func__);
1585 cry(conn, "%s: gethostbyname(%s): %s", __func__, host, strerror(ERRNO));
1587 cry(conn, "%s: socket: %s", __func__, strerror(ERRNO));
1593 cry(conn, "%s: connect(%s:%d): %s", __func__, host, port,
1598 cry(conn, "%s: calloc: %s", __func__, strerror(ERRNO));
2033 static FILE *open_auth_file(struct mg_connection *conn, const char *path) {
2034 struct mg_context *ctx = conn->ctx;
2047 (void) mg_snprintf(conn, name, sizeof(name), "%s%c%s",
2055 (void) mg_snprintf(conn, name, sizeof(name), "%.*s%c%s",
2068 static int parse_auth_header(struct mg_connection *conn, char *buf,
2073 if ((auth_header = mg_get_header(conn, "Authorization")) == NULL ||
2124 conn->request_info.remote_user = mg_strdup(ah->user);
2133 static int authorize(struct mg_connection *conn, FILE *fp) {
2137 if (!parse_auth_header(conn, buf, sizeof(buf), &ah)) {
2148 !strcmp(conn->ctx->config[AUTHENTICATION_DOMAIN], f_domain))
2150 conn->request_info.request_method,
2159 static int check_authorization(struct mg_connection *conn, const char *path) {
2169 list = conn->ctx->config[PROTECT_URI];
2171 if (!memcmp(conn
2172 (void) mg_snprintf(conn, fname, sizeof(fname), "%.*s",
2175 cry(conn, "%s: cannot open %s: %s", __func__, fname, strerror(errno));
2182 fp = open_auth_file(conn, path);
2186 authorized = authorize(conn, fp);
2193 static void send_authorization_request(struct mg_connection *conn) {
2194 conn->request_info.status_code = 401;
2195 (void) mg_printf(conn,
2200 conn->ctx->config[AUTHENTICATION_DOMAIN],
2204 static int is_authorized_for_put(struct mg_connection *conn) {
2208 fp = conn->ctx->config[PUT_DELETE_PASSWORDS_FILE] == NULL ? NULL :
2209 mg_fopen(conn->ctx->config[PUT_DELETE_PASSWORDS_FILE], "r");
2212 ret = authorize(conn, fp);
2283 struct mg_connection *conn;
2312 (void) mg_snprintf(de->conn, size, sizeof(size), "%s", "[DIRECTORY]");
2317 (void) mg_snprintf(de->conn, size, sizeof(size),
2320 (void) mg_snprintf(de->conn, size, sizeof(size),
2323 (void) mg_snprintf(de->conn, size, sizeof(size),
2326 (void) mg_snprintf(de->conn, size, sizeof(size),
2332 de->conn->num_bytes_sent += mg_printf(de->conn,
2335 de->conn->request_info.uri, href, de->st.is_directory ? "/" : "",
2345 const char *query_string = a->conn->request_info.query_string;
2369 static int scan_directory(struct mg_connection *conn, const char *dir,
2379 de.conn = conn;
2388 mg_snprintf(conn, path, sizeof(path), "%s%c%s", dir, DIRSEP, dp->d_name);
2427 dsd->entries[dsd->num_entries].conn = de->conn;
2432 static void handle_directory_request(struct mg_connection *conn,
2437 if (!scan_directory(conn, dir, &data, dir_scan_callback)) {
2438 send_http_error(conn, 500, "Cannot open directory",
2443 sort_direction = conn->request_info.query_string != NULL &&
2444 conn->request_info.query_string[1] == 'd' ? 'a' : 'd';
2446 mg_printf(conn, "%s",
2451 conn->num_bytes_sent += mg_printf(conn,
2459 conn->request_info.uri, conn->request_info.uri,
2463 conn->num_bytes_sent += mg_printf(conn,
2466 conn->request_info.uri, "..", "Parent directory", "-", "-");
2477 conn->num_bytes_sent += mg_printf(conn, "%s", "</table></body></html>");
2478 conn->request_info.status_code = 200;
2482 static void send_file_data(struct mg_connection *conn, FILE *fp, int64_t len) {
2497 if ((num_written = mg_write(conn, buf, (size_t)num_read)) != num_read)
2501 conn->num_bytes_sent += num_written;
2514 static void handle_file_request(struct mg_connection *conn, const char *path,
2524 get_mime_type(conn->ctx, path, &mime_vec);
2526 conn->request_info.status_code = 200;
2530 send_http_error(conn, 500, http_500_error,
2538 hdr = mg_get_header(conn, "Range");
2540 conn->request_info.status_code = 206;
2543 (void) mg_snprintf(conn, range, sizeof(range),
2555 (void) mg_snprintf(conn, etag, sizeof(etag), "%lx.%lx",
2558 (void) mg_printf(conn,
2568 conn->request_info.status_code, msg, date, lm, etag,
2569 mime_vec.len, mime_vec.ptr, cl, suggest_connection_header(conn), range);
2571 if (strcmp(conn->request_info.request_method, "HEAD") != 0) {
2572 send_file_data(conn, fp, cl);
2577 void mg_send_file(struct mg_connection *conn, const char *path) {
2580 handle_file_request(conn, path, &st);
2582 send_http_error(conn, 404, "Not Found", "%s", "File not found");
2657 static int substitute_index_file(struct mg_connection *conn, char *path,
2659 const char *list = conn->ctx->config[INDEX_FILES];
2702 static int is_not_modified(const struct mg_connection *conn,
2704 const char *ims = mg_get_header(conn, "If-Modified-Since");
2708 static int forward_body_data(struct mg_connection *conn, FILE *fp,
2714 expect = mg_get_header(conn, "Expect");
2717 if (conn->content_len == -1) {
2718 send_http_error(conn, 411, "Length Required", "");
2720 send_http_error(conn, 417, "Expectation Failed", "");
2723 (void) mg_printf(conn, "%s", "HTTP/1.1 100 Continue\r\n\r\n");
2726 buffered = conn->buf + conn->request_len;
2727 buffered_len = conn->data_len - conn->request_len;
2729 assert(conn->consumed_content == 0);
2732 if ((int64_t) buffered_len > conn->content_len) {
2733 buffered_len = (int) conn->content_len;
2736 conn->consumed_content += buffered_len;
2739 while (conn->consumed_content < conn->content_len) {
2741 if ((int64_t) to_read > conn->content_len - conn->consumed_content) {
2742 to_read = (int) (conn->content_len - conn->consumed_content);
2744 nread = pull(NULL, conn->client.sock, conn->ssl, buf, to_read);
2748 conn->consumed_content += nread;
2751 if (conn->consumed_content == conn->content_len) {
2757 send_http_error(conn, 577, http_500_error, "");
2774 struct mg_connection *conn;
2797 n = mg_vsnprintf(block->conn, added, (size_t) space, fmt, ap);
2812 static void prepare_cgi_environment(struct mg_connection *conn,
2821 blk->conn = conn;
2825 get_document_root(conn, &root);
2827 addenv(blk, "SERVER_NAME=%s", conn->ctx->config[AUTHENTICATION_DOMAIN]);
2835 addenv(blk, "SERVER_PORT=%d", ntohs(conn->client.lsa.u.sin.sin_port));
2836 addenv(blk, "REQUEST_METHOD=%s", conn->request_info.request_method);
2838 inet_ntoa(conn->client.rsa.u.sin.sin_addr));
2839 addenv(blk, "REMOTE_PORT=%d", conn->request_info.remote_port);
2840 addenv(blk, "REQUEST_URI=%s", conn->request_info.uri);
2843 assert(conn->request_info.uri[0] == '/');
2844 slash = strrchr(conn->request_info.uri, '/');
2847 addenv(blk, "SCRIPT_NAME=%.*s%s", slash - conn->request_info.uri,
2848 conn->request_info.uri, s);
2852 addenv(blk, "HTTPS=%s", conn->ssl == NULL ? "off" : "on");
2854 if ((s = mg_get_header(conn, "Content-Type")) != NULL)
2857 if (conn->request_info.query_string != NULL)
2858 addenv(blk, "QUERY_STRING=%s", conn->request_info.query_string);
2860 if ((s = mg_get_header(conn, "Content-Length")) != NULL)
2879 if (conn->request_info.remote_user != NULL) {
2880 addenv(blk, "REMOTE_USER=%s", conn->request_info.remote_user);
2885 for (i = 0; i < conn->request_info.num_headers; i++) {
2887 conn->request_info.http_headers[i].name,
2888 conn->request_info.http_headers[i].value);
2899 s = conn->ctx->config[CGI_ENVIRONMENT];
2912 static void handle_cgi_request(struct mg_connection *conn, const char *prog) {
2923 prepare_cgi_environment(conn, prog, &blk);
2928 (void) mg_snprintf(conn, dir, sizeof(dir), "%s", prog);
2941 send_http_error(conn, 500, http_500_error,
2944 } else if ((pid = spawn_process(conn, p, blk.buf, blk.vars,
2949 send_http_error(conn, 500, http_500_error,
2964 if (!strcmp(conn->request_info.request_method, "POST") &&
2965 !forward_body_data(conn, in, INVALID_SOCKET, NULL)) {
2977 send_http_error(conn, 500, http_500_error,
2988 conn->request_info.status_code = status == NULL ? 200 : atoi(status);
2989 (void) mg_printf(conn, "HTTP/1.1 %d OK\r\n", conn->request_info.status_code);
2993 mg_printf(conn, "%s: %s\r\n",
2996 (void) mg_write(conn, "\r\n", 2);
2999 conn->num_bytes_sent += mg_write(conn, buf + headers_len,
3003 send_file_data(conn, out, INT64_MAX);
3064 static void put_file(struct mg_connection *conn, const char *path) {
3071 conn->request_info.status_code = mg_stat(path, &st) == 0 ? 200 : 201;
3074 mg_printf(conn, "HTTP/1.1 %d OK\r\n\r\n", conn->request_info.status_code);
3076 send_http_error(conn, 500, http_500_error,
3079 send_http_error(conn, 500, http_500_error,
3083 range = mg_get_header(conn, "Content-Range");
3086 conn->request_info.status_code = 206;
3090 if (forward_body_data(conn, fp, INVALID_SOCKET, NULL))
3091 (void) mg_printf(conn, "HTTP/1.1 %d OK\r\n\r\n",
3092 conn->request_info.status_code);
3099 static void do_ssi_include(struct mg_connection *conn, const char *ssi,
3106 get_document_root(conn, &root);
3112 (void) mg_snprintf(conn, path, sizeof(path), "%.*s%c%s",
3117 (void) mg_snprintf(conn, path, sizeof(path), "%s", file_name);
3120 (void) mg_snprintf(conn, path, sizeof(path), "%s", ssi);
3124 (void) mg_snprintf(conn, path + strlen(path),
3127 cry(conn, "Bad SSI #include: [%s]", tag);
3132 cry(conn, "Cannot open SSI #include: [%s]: fopen(%s): %s",
3136 is_ssi = match_extension(path, conn->ctx->config[SSI_EXTENSIONS]);
3138 send_ssi_file(conn, path, fp, include_level + 1);
3140 send_file_data(conn, fp, INT64_MAX);
3147 static void do_ssi_exec(struct mg_connection *conn, char *tag) {
3152 cry(conn, "Bad SSI #exec: [%s]", tag);
3154 cry(conn, "Cannot SSI #exec: [%s]: %s", cmd, strerror(ERRNO));
3156 send_file_data(conn, fp, INT64_MAX);
3162 static void send_ssi_file(struct mg_connection *conn, const char *path,
3168 cry(conn, "SSI #include level is too deep (%s)", path);
3183 (void) mg_write(conn, buf, (size_t)len);
3186 do_ssi_include(conn, path, buf + 12, include_level);
3189 do_ssi_exec(conn, buf + 9);
3192 cry(conn, "%s: unknown SSI " "command: \"%s\"", path, buf);
3201 cry(conn, "%s: SSI tag is too large", path);
3208 (void) mg_write(conn, buf, (size_t)len);
3215 (void) mg_write(conn, buf, (size_t)len);
3223 (void) mg_write(conn, buf, (size_t)len);
3227 static void handle_ssi_file_request(struct mg_connection *conn,
3232 send_http_error(conn, 500, http_500_error, "fopen(%s): %s", path,
3236 mg_printf(conn, "HTTP/1.1 200 OK\r\n"
3238 suggest_connection_header(conn));
3239 send_ssi_file(conn, path, fp, 0);
3244 static void send_options(struct mg_connection *conn) {
3245 conn->request_info.status_code = 200;
3247 (void) mg_printf(conn,
3254 static void print_props(struct mg_connection *conn, const char* uri,
3258 conn->num_bytes_sent += mg_printf(conn,
3278 struct mg_connection *conn = (struct mg_connection *) data;
3279 mg_snprintf(conn, href, sizeof(href), "%s%s",
3280 conn->request_info.uri, de->file_name);
3281 print_props(conn, href, &de->st);
3284 static void handle_propfind(struct mg_connection *conn, const char* path,
3286 const char *depth = mg_get_header(conn, "Depth");
3288 conn->request_info.status_code = 207;
3289 mg_printf(conn, "HTTP/1.1 207 Multi-Status\r\n"
3293 conn->num_bytes_sent += mg_printf(conn,
3298 print_props(conn, conn->request_info.uri, st);
3302 !mg_strcasecmp(conn->ctx->config[ENABLE_DIRECTORY_LISTING], "yes") &&
3304 scan_directory(conn, path, conn, &print_dav_dir_entry);
3307 conn->num_bytes_sent += mg_printf(conn, "%s\n", "</d:multistatus>");
3314 static void handle_request(struct mg_connection *conn) {
3315 struct mg_request_info *ri = &conn->request_info;
3320 if ((conn->request_info.query_string = strchr(ri->uri, '?')) != NULL) {
3321 * conn->request_info.query_string++ = '\0';
3326 convert_uri_to_file_name(conn, ri->uri, path, sizeof(path));
3329 if (!check_authorization(conn, path)) {
3330 send_authorization_request(conn);
3331 } else if (call_user(conn, MG_NEW_REQUEST) != NULL) {
3334 send_options(conn);
3337 send_http_error(conn, 403, "Forbidden", "Access Forbidden");
3338 } else if (conn->ctx->config[DOCUMENT_ROOT] == NULL) {
3339 send_http_error(conn, 404, "Not Found", "Not Found");
3342 (conn->ctx->config[PUT_DELETE_PASSWORDS_FILE] == NULL ||
3343 !is_authorized_for_put(conn))) {
3344 send_authorization_request(conn);
3346 put_file(conn, path);
3349 send_http_error(conn, 200, "OK", "");
3351 send_http_error(conn, 500, http_500_error, "remove(%s): %s", path,
3355 send_http_error(conn, 404, "Not Found", "%s", "File not found");
3357 (void) mg_printf(conn,
3361 handle_propfind(conn, path, &st);
3363 !substitute_index_file(conn, path, sizeof(path), &st)) {
3364 if (!mg_strcasecmp(conn->ctx->config[ENABLE_DIRECTORY_LISTING], "yes")) {
3365 handle_directory_request(conn, path);
3367 send_http_error(conn, 403, "Directory Listing Denied",
3371 } else if (match_extension(path, conn->ctx->config[CGI_EXTENSIONS])) {
3374 send_http_error(conn, 501, "Not Implemented",
3377 handle_cgi_request(conn, path);
3380 } else if (match_extension(path, conn->ctx->config[SSI_EXTENSIONS])) {
3381 handle_ssi_file_request(conn, path);
3382 } else if (is_not_modified(conn, &st)) {
3383 send_http_error(conn, 304, "Not Modified", "");
3385 handle_file_request(conn, path, &st);
3495 static void log_header(const struct mg_connection *conn, const char *header,
3499 if ((header_value = mg_get_header(conn, header)) == NULL) {
3506 static void log_access(const struct mg_connection *conn) {
3511 fp = conn->ctx->config[ACCESS_LOG_FILE] == NULL ? NULL :
3512 mg_fopen(conn->ctx->config[ACCESS_LOG_FILE], "a+");
3518 localtime(&conn->birth_time));
3520 ri = &conn->request_info;
3526 inet_ntoa(conn->client.rsa.u.sin.sin_addr),
3532 conn->request_info.status_code, conn->num_bytes_sent);
3533 log_header(conn, "Referer", fp);
3534 log_header(conn, "User-Agent", fp);
3770 static void reset_per_request_attributes(struct mg_connection *conn) {
3771 struct mg_request_info *ri = &conn->request_info;
3781 conn->num_bytes_sent = conn->consumed_content = 0;
3782 conn->content_len = -1;
3783 conn->request_len = conn->data_len = 0;
3807 static void close_connection(struct mg_connection *conn) {
3808 if (conn->ssl) {
3809 SSL_free(conn->ssl);
3810 conn->ssl = NULL;
3813 if (conn->client.sock != INVALID_SOCKET) {
3814 close_socket_gracefully(conn->client.sock);
3818 static void discard_current_request_from_buffer(struct mg_connection *conn) {
3821 buffered_len = conn->data_len - conn->request_len;
3824 if (conn->content_len == -1) {
3826 } else if (conn->content_len < (int64_t) buffered_len) {
3827 body_len = (int) conn->content_len;
3832 conn->data_len -= conn->request_len + body_len;
3833 memmove(conn->buf, conn->buf + conn->request_len + body_len,
3834 (size_t) conn->data_len);
3853 static void handle_proxy_request(struct mg_connection *conn) {
3854 struct mg_request_info *ri = &conn->request_info;
3865 if (conn->peer == NULL) {
3867 if ((conn->peer = mg_connect(conn, host, port, is_ssl)) == NULL) {
3870 conn->peer->client.is_ssl = is_ssl;
3874 mg_printf(conn->peer, "%s %s HTTP/%s\r\n", ri->request_method, ri->uri + len,
3879 mg_printf(conn->peer, "%s: %s\r\n", ri->http_headers[i].name,
3883 mg_write(conn->peer, "\r\n", 2);
3887 forward_body_data(conn, NULL, conn->peer->client.sock, conn->peer->ssl);
3891 while ((n = pull(NULL, conn->peer->client.sock, conn->peer->ssl,
3893 if (mg_write(conn, buf, (size_t)n) != n) {
3898 if (!conn->peer->client.is_ssl) {
3899 close_connection(conn->peer);
3900 free(conn->peer);
3901 conn->peer = NULL;
3911 static void process_new_connection(struct mg_connection *conn) {
3912 struct mg_request_info *ri = &conn->request_info;
3916 keep_alive_enabled = !strcmp(conn->ctx->config[ENABLE_KEEP_ALIVE], "yes");
3919 reset_per_request_attributes(conn);
3922 if ((conn->request_len = get_request_len(conn->buf, conn->data_len)) == 0) {
3923 conn->request_len = read_request(NULL, conn->client.sock, conn->ssl,
3924 conn->buf, conn->buf_size, &conn->data_len);
3926 assert(conn->data_len >= conn->request_len);
3927 if (conn->request_len == 0 && conn->data_len == conn->buf_size) {
3928 send_http_error(conn, 413, "Request Too Large", "");
3930 } if (conn->request_len <= 0) {
3935 conn->buf[conn->request_len - 1] = '\0';
3936 if (!parse_http_request(conn->buf, ri) ||
3937 (!conn->client.is_proxy && !is_valid_uri(ri->uri))) {
3939 send_http_error(conn, 400, "Bad Request",
3940 "Cannot parse HTTP request: [%.*s]", conn->data_len, conn->buf);
3944 send_http_error(conn, 505, "HTTP version not supported", "");
3945 log_access(conn);
3949 conn->content_len = cl == NULL ? -1 : strtoll(cl, NULL, 10);
3950 conn->birth_time = time(NULL);
3951 if (conn->client.is_proxy) {
3952 handle_proxy_request(conn);
3954 handle_request(conn);
3956 log_access(conn);
3957 discard_current_request_from_buffer(conn);
3959 // conn->peer is not NULL only for SSL-ed proxy connections
3960 } while (conn->ctx->stop_flag == 0 &&
3961 (conn->peer || (keep_alive_enabled && should_keep_alive(conn))));
3995 struct mg_connection *conn;
3998 conn = (struct mg_connection *) calloc(1, sizeof(*conn) + buf_size);
3999 conn->buf_size = buf_size;
4000 conn->buf = (char *) (conn + 1);
4001 assert(conn != NULL);
4005 while (consume_socket(ctx, &conn->client)) {
4006 conn->birth_time = time(NULL);
4007 conn->ctx = ctx;
4012 conn->request_info.remote_port = ntohs(conn->client.rsa.u.sin.sin_port);
4013 memcpy(&conn->request_info.remote_ip,
4014 &conn->client.rsa.u.sin.sin_addr.s_addr, 4);
4015 conn->request_info.remote_ip = ntohl(conn->request_info.remote_ip);
4016 conn->request_info.is_ssl = conn->client.is_ssl;
4018 if (!conn->client.is_ssl ||
4019 (conn->client.is_ssl && sslize(conn, SSL_accept))) {
4020 process_new_connection(conn);
4023 close_connection(conn);
4025 free(conn);