allow to report that a client allows redirection with POST method

If clients sends POST /test, it notifies the server that it is
available for receive redirections from file 'test'.

Test it with wget:

  wget --post-data '' http://localhost:9999/TEST -O /dev/null
master
tiptorrent development team 2021-09-17 16:45:52 +02:00
parent dab82c806f
commit 16cc92dab6
3 changed files with 23 additions and 7 deletions

View File

@ -32,8 +32,6 @@ int num_clients;
static LIST_HEAD(client_list); static LIST_HEAD(client_list);
static LIST_HEAD(client_redirect_list); static LIST_HEAD(client_redirect_list);
static void tip_client_activate_pending(void);
static void tip_client_release(struct ev_loop *loop, struct tip_client *cli) static void tip_client_release(struct ev_loop *loop, struct tip_client *cli)
{ {
syslog(LOG_INFO, "closing connection with %s:%hu", syslog(LOG_INFO, "closing connection with %s:%hu",
@ -111,8 +109,6 @@ static int tip_client_recv(struct tip_client *cli, int events)
return ret; return ret;
} }
static int tip_client_redirect_create(const struct tip_client *cli);
static void tip_client_read_cb(struct ev_loop *loop, struct ev_io *io, int events) static void tip_client_read_cb(struct ev_loop *loop, struct ev_io *io, int events)
{ {
struct tip_client *cli; struct tip_client *cli;
@ -217,7 +213,7 @@ static void tip_client_redirect_timer_cb(struct ev_loop *loop, ev_timer *timer,
free(redir); free(redir);
} }
static int tip_client_redirect_create(const struct tip_client *cli) int tip_client_redirect_create(const struct tip_client *cli)
{ {
struct tip_client_redirect *redir; struct tip_client_redirect *redir;
bool found = false; bool found = false;
@ -353,7 +349,7 @@ void tip_client_pending(struct tip_client *cli)
cli->state = TIP_CLIENT_PENDING; cli->state = TIP_CLIENT_PENDING;
} }
static void tip_client_activate_pending(void) void tip_client_activate_pending(void)
{ {
struct tip_client *cli, *next; struct tip_client *cli, *next;

View File

@ -29,6 +29,7 @@ enum tip_client_state {
enum tip_http_method { enum tip_http_method {
TIP_METHOD_GET = 0, TIP_METHOD_GET = 0,
TIP_METHOD_HEAD, TIP_METHOD_HEAD,
TIP_METHOD_POST,
}; };
struct tip_client { struct tip_client {
@ -69,6 +70,8 @@ static inline bool tip_client_large_file(const struct tip_client *cli)
void tip_client_pending(struct tip_client *cli); void tip_client_pending(struct tip_client *cli);
bool tip_client_redirect(struct tip_client *cli); bool tip_client_redirect(struct tip_client *cli);
int tip_client_redirect_create(const struct tip_client *cli);
void tip_client_activate_pending(void);
extern struct ev_loop *tip_main_loop; extern struct ev_loop *tip_main_loop;

View File

@ -74,6 +74,10 @@ int tip_client_state_process_payload(struct tip_client *cli)
cli->method = TIP_METHOD_HEAD; cli->method = TIP_METHOD_HEAD;
if (sscanf(cli->buf, "HEAD %31s HTTP/1.1", uri) != 1) if (sscanf(cli->buf, "HEAD %31s HTTP/1.1", uri) != 1)
return tip_client_method_not_found(cli); return tip_client_method_not_found(cli);
} else if (!strncmp(cli->buf, "POST", strlen("POST"))) {
cli->method = TIP_METHOD_POST;
if (sscanf(cli->buf, "POST %31s HTTP/1.1", uri) != 1)
return tip_client_method_not_found(cli);
} else { } else {
return tip_client_method_not_found(cli); return tip_client_method_not_found(cli);
} }
@ -102,7 +106,16 @@ int tip_client_state_process_payload(struct tip_client *cli)
cli->path = strdup(path); cli->path = strdup(path);
cli->size = st.st_size; cli->size = st.st_size;
if (cli->method == TIP_METHOD_HEAD) { switch (cli->method) {
case TIP_METHOD_GET:
break;
case TIP_METHOD_HEAD:
cli->state = TIP_CLIENT_PROCESSING_REQUEST_2;
return 0;
case TIP_METHOD_POST:
cli->allow_redirect = true;
tip_client_redirect_create(cli);
tip_client_activate_pending();
cli->state = TIP_CLIENT_PROCESSING_REQUEST_2; cli->state = TIP_CLIENT_PROCESSING_REQUEST_2;
return 0; return 0;
} }
@ -143,6 +156,9 @@ int tip_client_state_process_payload_reply(struct tip_client *cli)
if (fd < 0) if (fd < 0)
return tip_client_file_not_found(cli); return tip_client_file_not_found(cli);
if (cli->method == TIP_METHOD_POST)
cli->size = 0;
snprintf(buf, sizeof(buf), snprintf(buf, sizeof(buf),
"HTTP/1.1 200 OK\r\nContent-Length: %lu\r\n\r\n", "HTTP/1.1 200 OK\r\nContent-Length: %lu\r\n\r\n",
cli->size); cli->size);
@ -155,6 +171,7 @@ int tip_client_state_process_payload_reply(struct tip_client *cli)
cli->state = TIP_CLIENT_PROCESSING_REQUEST_3; cli->state = TIP_CLIENT_PROCESSING_REQUEST_3;
break; break;
case TIP_METHOD_HEAD: case TIP_METHOD_HEAD:
case TIP_METHOD_POST:
/* close connection. */ /* close connection. */
return 1; return 1;
} }