static void on_read_proxy_line(h2o_socket_t *sock, int status) { struct st_h2o_accept_data_t *data = sock->data; if (status != 0) { free_accept_data(data); h2o_socket_close(sock); return; } struct sockaddr_storage addr; socklen_t addrlen; ssize_t r = parse_proxy_line(sock->input->bytes, sock->input->size, (void *)&addr, &addrlen); switch (r) { case -1: /* error, just pass the input to the next handler */ break; case -2: /* incomplete */ return; default: h2o_buffer_consume(&sock->input, r); if (addrlen != 0) h2o_socket_setpeername(sock, (void *)&addr, addrlen); break; } if (data->ctx->ssl_ctx != NULL) { h2o_socket_ssl_server_handshake(sock, data->ctx->ssl_ctx, on_ssl_handshake_complete); } else { h2o_accept_ctx_t *ctx = free_accept_data(data); sock->data = NULL; h2o_http1_accept(ctx, sock); } }
static void test_parse_proxy_line(void) { char in[256]; struct sockaddr_storage sa; socklen_t salen; ssize_t ret; strcpy(in, ""); ret = parse_proxy_line(in, strlen(in), (void *)&sa, &salen); ok(ret == -2); strcpy(in, "PROXY TCP4 192.168.0.1 192.168.0.11 56324 443\r\nabc"); ret = parse_proxy_line(in, strlen(in), (void *)&sa, &salen); ok(ret == strlen(in) - 3); ok(salen == sizeof(struct sockaddr_in)); ok(sa.ss_family == AF_INET); ok(((struct sockaddr_in *)&sa)->sin_addr.s_addr == htonl(0xc0a80001)); ok(((struct sockaddr_in *)&sa)->sin_port == htons(56324)); strcpy(in, "PROXY TCP4 192.168.0.1 192.168.0.11 56324 443\r"); ret = parse_proxy_line(in, strlen(in), (void *)&sa, &salen); ok(ret == -2); strcpy(in, "PROXY TCP5"); ret = parse_proxy_line(in, strlen(in), (void *)&sa, &salen); ok(ret == -1); strcpy(in, "PROXY UNKNOWN"); ret = parse_proxy_line(in, strlen(in), (void *)&sa, &salen); ok(ret == -2); strcpy(in, "PROXY UNKNOWN\r\nabc"); ret = parse_proxy_line(in, strlen(in), (void *)&sa, &salen); ok(ret == strlen(in) - 3); ok(salen == 0); strcpy(in, "PROXY TCP6 ::1 ::1 56324 443\r\n"); ret = parse_proxy_line(in, strlen(in), (void *)&sa, &salen); ok(ret == strlen(in)); ok(salen == sizeof(struct sockaddr_in6)); ok(sa.ss_family == AF_INET6); ok(memcmp(&((struct sockaddr_in6 *)&sa)->sin6_addr, H2O_STRLIT("\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\1")) == 0); ok(((struct sockaddr_in6 *)&sa)->sin6_port == htons(56324)); }