Add support for cloning over http
This patch implements basic support for cloning over http, based on the work on git-http-backend by Shawn O. Pearce. Signed-off-by: Lars Hjemli <hjemli@gmail.com>
Этот коммит содержится в:
		
							
								
								
									
										1
									
								
								Makefile
									
									
									
									
									
								
							
							
						
						
									
										1
									
								
								Makefile
									
									
									
									
									
								
							| @@ -56,6 +56,7 @@ OBJECTS += html.o | ||||
| OBJECTS += parsing.o | ||||
| OBJECTS += shared.o | ||||
| OBJECTS += ui-blob.o | ||||
| OBJECTS += ui-clone.o | ||||
| OBJECTS += ui-commit.o | ||||
| OBJECTS += ui-diff.o | ||||
| OBJECTS += ui-log.o | ||||
|   | ||||
							
								
								
									
										19
									
								
								cmd.c
									
									
									
									
									
								
							
							
						
						
									
										19
									
								
								cmd.c
									
									
									
									
									
								
							| @@ -11,6 +11,7 @@ | ||||
| #include "cache.h" | ||||
| #include "ui-shared.h" | ||||
| #include "ui-blob.h" | ||||
| #include "ui-clone.h" | ||||
| #include "ui-commit.h" | ||||
| #include "ui-diff.h" | ||||
| #include "ui-log.h" | ||||
| @@ -22,6 +23,11 @@ | ||||
| #include "ui-tag.h" | ||||
| #include "ui-tree.h" | ||||
|  | ||||
| static void HEAD_fn(struct cgit_context *ctx) | ||||
| { | ||||
| 	cgit_clone_head(ctx); | ||||
| } | ||||
|  | ||||
| static void about_fn(struct cgit_context *ctx) | ||||
| { | ||||
| 	if (ctx->repo) | ||||
| @@ -45,6 +51,11 @@ static void diff_fn(struct cgit_context *ctx) | ||||
| 	cgit_print_diff(ctx->qry.sha1, ctx->qry.sha2, ctx->qry.path); | ||||
| } | ||||
|  | ||||
| static void info_fn(struct cgit_context *ctx) | ||||
| { | ||||
| 	cgit_clone_info(ctx); | ||||
| } | ||||
|  | ||||
| static void log_fn(struct cgit_context *ctx) | ||||
| { | ||||
| 	cgit_print_log(ctx->qry.sha1, ctx->qry.ofs, ctx->cfg.max_commit_count, | ||||
| @@ -59,6 +70,11 @@ static void ls_cache_fn(struct cgit_context *ctx) | ||||
| 	cache_ls(ctx->cfg.cache_root); | ||||
| } | ||||
|  | ||||
| static void objects_fn(struct cgit_context *ctx) | ||||
| { | ||||
| 	cgit_clone_objects(ctx); | ||||
| } | ||||
|  | ||||
| static void repolist_fn(struct cgit_context *ctx) | ||||
| { | ||||
| 	cgit_print_repolist(); | ||||
| @@ -102,12 +118,15 @@ static void tree_fn(struct cgit_context *ctx) | ||||
| struct cgit_cmd *cgit_get_cmd(struct cgit_context *ctx) | ||||
| { | ||||
| 	static struct cgit_cmd cmds[] = { | ||||
| 		def_cmd(HEAD, 1, 0), | ||||
| 		def_cmd(about, 0, 1), | ||||
| 		def_cmd(blob, 1, 0), | ||||
| 		def_cmd(commit, 1, 1), | ||||
| 		def_cmd(diff, 1, 1), | ||||
| 		def_cmd(info, 1, 0), | ||||
| 		def_cmd(log, 1, 1), | ||||
| 		def_cmd(ls_cache, 0, 0), | ||||
| 		def_cmd(objects, 1, 0), | ||||
| 		def_cmd(patch, 1, 0), | ||||
| 		def_cmd(refs, 1, 1), | ||||
| 		def_cmd(repolist, 0, 0), | ||||
|   | ||||
							
								
								
									
										7
									
								
								html.c
									
									
									
									
									
								
							
							
						
						
									
										7
									
								
								html.c
									
									
									
									
									
								
							| @@ -51,6 +51,13 @@ void htmlf(const char *format, ...) | ||||
| 	html(buf); | ||||
| } | ||||
|  | ||||
| void html_status(int code, int more_headers) | ||||
| { | ||||
| 	htmlf("Status: %d\n", code); | ||||
| 	if (!more_headers) | ||||
| 		html("\n"); | ||||
| } | ||||
|  | ||||
| void html_txt(char *txt) | ||||
| { | ||||
| 	char *t = txt; | ||||
|   | ||||
							
								
								
									
										1
									
								
								html.h
									
									
									
									
									
								
							
							
						
						
									
										1
									
								
								html.h
									
									
									
									
									
								
							| @@ -5,6 +5,7 @@ extern int htmlfd; | ||||
|  | ||||
| extern void html(const char *txt); | ||||
| extern void htmlf(const char *format,...); | ||||
| extern void html_status(int code, int more_headers); | ||||
| extern void html_txt(char *txt); | ||||
| extern void html_ntxt(int len, char *txt); | ||||
| extern void html_attr(char *txt); | ||||
|   | ||||
							
								
								
									
										104
									
								
								ui-clone.c
									
									
									
									
									
										Обычный файл
									
								
							
							
						
						
									
										104
									
								
								ui-clone.c
									
									
									
									
									
										Обычный файл
									
								
							| @@ -0,0 +1,104 @@ | ||||
| /* ui-clone.c: functions for http cloning, based on | ||||
|  * git's http-backend.c by Shawn O. Pearce | ||||
|  * | ||||
|  * Copyright (C) 2008 Lars Hjemli | ||||
|  * | ||||
|  * Licensed under GNU General Public License v2 | ||||
|  *   (see COPYING for full license text) | ||||
|  */ | ||||
|  | ||||
| #include "cgit.h" | ||||
| #include "html.h" | ||||
| #include "ui-shared.h" | ||||
|  | ||||
| static int print_ref_info(const char *refname, const unsigned char *sha1, | ||||
|                           int flags, void *cb_data) | ||||
| { | ||||
| 	struct object *obj; | ||||
|  | ||||
| 	if (!(obj = parse_object(sha1))) | ||||
| 		return 0; | ||||
|  | ||||
| 	if (!strcmp(refname, "HEAD") || !prefixcmp(refname, "refs/heads/")) | ||||
| 		htmlf("%s\t%s\n", sha1_to_hex(sha1), refname); | ||||
| 	else if (!prefixcmp(refname, "refs/tags") && obj->type == OBJ_TAG) { | ||||
| 		if (!(obj = deref_tag(obj, refname, 0))) | ||||
| 			return 0; | ||||
| 		htmlf("%s\t%s\n", sha1_to_hex(sha1), refname); | ||||
| 		htmlf("%s\t%s^{}\n", sha1_to_hex(obj->sha1), refname); | ||||
| 	} | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| static void print_pack_info(struct cgit_context *ctx) | ||||
| { | ||||
| 	struct packed_git *pack; | ||||
| 	int ofs; | ||||
|  | ||||
| 	ctx->page.mimetype = "text/plain"; | ||||
| 	ctx->page.filename = "objects/info/packs"; | ||||
| 	cgit_print_http_headers(ctx); | ||||
| 	ofs = strlen(ctx->repo->path) + strlen("/objects/pack/"); | ||||
| 	prepare_packed_git(); | ||||
| 	for (pack = packed_git; pack; pack = pack->next) | ||||
| 		if (pack->pack_local) | ||||
| 			htmlf("P %s\n", pack->pack_name + ofs); | ||||
| } | ||||
|  | ||||
| static void send_file(struct cgit_context *ctx, char *path) | ||||
| { | ||||
| 	struct stat st; | ||||
| 	int err; | ||||
|  | ||||
| 	if (stat(path, &st)) { | ||||
| 		switch (errno) { | ||||
| 		case ENOENT: | ||||
| 			err = 404; | ||||
| 			break; | ||||
| 		case EACCES: | ||||
| 			err = 403; | ||||
| 			break; | ||||
| 		default: | ||||
| 			err = 400; | ||||
| 		} | ||||
| 		html_status(err, 0); | ||||
| 		return; | ||||
| 	} | ||||
| 	ctx->page.mimetype = "application/octet-stream"; | ||||
| 	ctx->page.filename = path; | ||||
| 	if (prefixcmp(ctx->repo->path, path)) | ||||
| 		ctx->page.filename += strlen(ctx->repo->path) + 1; | ||||
| 	cgit_print_http_headers(ctx); | ||||
| 	html_include(path); | ||||
| } | ||||
|  | ||||
| void cgit_clone_info(struct cgit_context *ctx) | ||||
| { | ||||
| 	if (!ctx->qry.path || strcmp(ctx->qry.path, "refs")) | ||||
| 		return; | ||||
|  | ||||
| 	ctx->page.mimetype = "text/plain"; | ||||
| 	ctx->page.filename = "info/refs"; | ||||
| 	cgit_print_http_headers(ctx); | ||||
| 	for_each_ref(print_ref_info, ctx); | ||||
| } | ||||
|  | ||||
| void cgit_clone_objects(struct cgit_context *ctx) | ||||
| { | ||||
| 	if (!ctx->qry.path) { | ||||
| 		html_status(400, 0); | ||||
| 		return; | ||||
| 	} | ||||
|  | ||||
| 	if (!strcmp(ctx->qry.path, "info/packs")) { | ||||
| 		print_pack_info(ctx); | ||||
| 		return; | ||||
| 	} | ||||
|  | ||||
| 	send_file(ctx, git_path("objects/%s", ctx->qry.path)); | ||||
| } | ||||
|  | ||||
| void cgit_clone_head(struct cgit_context *ctx) | ||||
| { | ||||
| 	send_file(ctx, git_path("%s", "HEAD")); | ||||
| } | ||||
							
								
								
									
										8
									
								
								ui-clone.h
									
									
									
									
									
										Обычный файл
									
								
							
							
						
						
									
										8
									
								
								ui-clone.h
									
									
									
									
									
										Обычный файл
									
								
							| @@ -0,0 +1,8 @@ | ||||
| #ifndef UI_CLONE_H | ||||
| #define UI_CLONE_H | ||||
|  | ||||
| void cgit_clone_info(struct cgit_context *ctx); | ||||
| void cgit_clone_objects(struct cgit_context *ctx); | ||||
| void cgit_clone_head(struct cgit_context *ctx); | ||||
|  | ||||
| #endif /* UI_CLONE_H */ | ||||
		Ссылка в новой задаче
	
	Block a user
	 Lars Hjemli
					Lars Hjemli