Skip to content

Commit a5d4f6c

Browse files
committed
server: first steps
Let's start with baby steps, by letting the server figure out what type of request the user wants. This includes some include guards for internal headers, which apparently we've only ever included once up to now.
1 parent 39bbc55 commit a5d4f6c

File tree

5 files changed

+147
-0
lines changed

5 files changed

+147
-0
lines changed

include/git2/types.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -180,6 +180,8 @@ typedef struct git_merge_result git_merge_result;
180180
/** Representation of a status collection */
181181
typedef struct git_status_list git_status_list;
182182

183+
/** A server */
184+
typedef struct git_server git_server;
183185

184186
/** Basic type of any Git reference. */
185187
typedef enum {

src/server.c

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
/*
2+
* Copyright (C) the libgit2 contributors. All rights reserved.
3+
*
4+
* This file is part of libgit2, distributed under the GNU GPL v2 with
5+
* a Linking Exception. For full terms see the included COPYING file.
6+
*/
7+
8+
#include "server.h"
9+
#include "netops.h"
10+
11+
int git_server_new(git_server **out, int fd)
12+
{
13+
git_server *server;
14+
15+
server = git__calloc(1, sizeof(git_server));
16+
GITERR_CHECK_ALLOC(server);
17+
18+
server->s.socket = fd;
19+
20+
*out = server;
21+
return 0;
22+
}
23+
24+
void git_server_free(git_server *server)
25+
{
26+
if (server == NULL)
27+
return;
28+
29+
git__free(server->path);
30+
git__free(server);
31+
}
32+
33+
int git_server__handle_request(git_server *server, git_pkt *pkt)
34+
{
35+
git_pkt_request *req;
36+
37+
if (pkt->type != GIT_PKT_REQUEST) {
38+
giterr_set(GITERR_NET, "first line was not a request");
39+
return -1;
40+
}
41+
42+
req = (git_pkt_request *) pkt;
43+
server->type = req->request;
44+
server->path = git__strdup(req->path);
45+
GITERR_CHECK_ALLOC(server->path);
46+
47+
return 0;
48+
}
49+
50+
int git_server_run(git_server *server)
51+
{
52+
/* 65535 is the max size of a pkt frame */
53+
char buffer[65536] = {0};
54+
gitno_buffer buf;
55+
gitno_socket *s = &server->s;
56+
int error;
57+
58+
gitno_buffer_setup(s, &buf, buffer, sizeof(buffer));
59+
60+
/* first we figure out which service the user wants */
61+
while (1) {
62+
git_pkt *pkt;
63+
const char *rest;
64+
65+
66+
if ((error = gitno_recv(&buf)) < 0)
67+
return error;
68+
69+
error = git_pkt_parse_line(&pkt, buffer, &rest, buf.len);
70+
if (error == GIT_EBUFS)
71+
continue;
72+
73+
if (error < 0)
74+
return error;
75+
76+
gitno_consume(&buf, rest);
77+
78+
error = git_server__handle_request(server, pkt);
79+
git_pkt_free(pkt);
80+
81+
if (error < 0)
82+
return error;
83+
84+
break;
85+
}
86+
87+
return 0;
88+
}

src/server.h

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
/*
2+
* Copyright (C) the libgit2 contributors. All rights reserved.
3+
*
4+
* This file is part of libgit2, distributed under the GNU GPL v2 with
5+
* a Linking Exception. For full terms see the included COPYING file.
6+
*/
7+
#ifndef INCLUDE_server_h__
8+
#define INCLUDE_server_h__
9+
10+
#include "common.h"
11+
#include "transports/smart.h"
12+
13+
struct git_server {
14+
enum git_request_type type;
15+
gitno_socket s;
16+
int rpc;
17+
char *path;
18+
};
19+
20+
extern int git_server_new(git_server **out, int fd);
21+
extern void git_server_free(git_server *server);
22+
extern int git_server__handle_request(git_server *server, git_pkt *pkt);
23+
24+
#endif
25+

src/transports/smart.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,10 @@
44
* This file is part of libgit2, distributed under the GNU GPL v2 with
55
* a Linking Exception. For full terms see the included COPYING file.
66
*/
7+
8+
#ifndef INCLUDE_transports_smart_h__
9+
#define INCLUDE_transports_smart_h__
10+
711
#include "git2.h"
812
#include "vector.h"
913
#include "netops.h"
@@ -199,3 +203,5 @@ int git_pkt_buffer_done(git_buf *buf);
199203
int git_pkt_buffer_wants(const git_remote_head * const *refs, size_t count, transport_smart_caps *caps, git_buf *buf);
200204
int git_pkt_buffer_have(git_oid *oid, git_buf *buf);
201205
void git_pkt_free(git_pkt *pkt);
206+
207+
#endif

tests/network/server.c

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
#include "clar_libgit2.h"
2+
#include "transports/smart.h"
3+
#include "server.h"
4+
5+
static git_server *g_server;
6+
static git_pkt *g_pkt;
7+
8+
void test_network_server__cleanup(void)
9+
{
10+
git_pkt_free(g_pkt);
11+
git_server_free(g_server);
12+
}
13+
14+
void test_network_server__request_type(void)
15+
{
16+
const char buf[] = "0032git-upload-pack /project.git\0host=myserver.com\0";
17+
const char *rest;
18+
size_t buflen = sizeof(buf);
19+
20+
cl_git_pass(git_server_new(&g_server, 0));
21+
cl_git_pass(git_pkt_parse_line(&g_pkt, buf, &rest, buflen));
22+
cl_git_pass(git_server__handle_request(g_server, g_pkt));
23+
24+
cl_assert_equal_i(GIT_REQUEST_UPLOAD_PACK, g_server->type);
25+
cl_assert_equal_s("/project.git", g_server->path);
26+
}

0 commit comments

Comments
 (0)