]> gitweb.ps.run Git - ps-cgit/blob - ui-clone.c
refactor get_mimetype_from_file() to get_mimetype_for_filename()
[ps-cgit] / ui-clone.c
1 /* ui-clone.c: functions for http cloning, based on
2  * git's http-backend.c by Shawn O. Pearce
3  *
4  * Copyright (C) 2006-2014 cgit Development Team <cgit@lists.zx2c4.com>
5  *
6  * Licensed under GNU General Public License v2
7  *   (see COPYING for full license text)
8  */
9
10 #include "cgit.h"
11 #include "ui-clone.h"
12 #include "html.h"
13 #include "ui-shared.h"
14
15 static int print_ref_info(const char *refname, const struct object_id *oid,
16                           int flags, void *cb_data)
17 {
18         struct object *obj;
19
20         if (!(obj = parse_object(oid->hash)))
21                 return 0;
22
23         htmlf("%s\t%s\n", oid_to_hex(oid), refname);
24         if (obj->type == OBJ_TAG) {
25                 if (!(obj = deref_tag(obj, refname, 0)))
26                         return 0;
27                 htmlf("%s\t%s^{}\n", sha1_to_hex(obj->sha1), refname);
28         }
29         return 0;
30 }
31
32 static void print_pack_info(void)
33 {
34         struct packed_git *pack;
35         char *offset;
36
37         ctx.page.mimetype = "text/plain";
38         ctx.page.filename = "objects/info/packs";
39         cgit_print_http_headers();
40         prepare_packed_git();
41         for (pack = packed_git; pack; pack = pack->next) {
42                 if (pack->pack_local) {
43                         offset = strrchr(pack->pack_name, '/');
44                         if (offset && offset[1] != '\0')
45                                 ++offset;
46                         else
47                                 offset = pack->pack_name;
48                         htmlf("P %s\n", offset);
49                 }
50         }
51 }
52
53 static void send_file(const char *path)
54 {
55         struct stat st;
56
57         if (stat(path, &st)) {
58                 switch (errno) {
59                 case ENOENT:
60                         cgit_print_error_page(404, "Not found", "Not found");
61                         break;
62                 case EACCES:
63                         cgit_print_error_page(403, "Forbidden", "Forbidden");
64                         break;
65                 default:
66                         cgit_print_error_page(400, "Bad request", "Bad request");
67                 }
68                 return;
69         }
70         ctx.page.mimetype = "application/octet-stream";
71         ctx.page.filename = path;
72         skip_prefix(path, ctx.repo->path, &ctx.page.filename);
73         skip_prefix(ctx.page.filename, "/", &ctx.page.filename);
74         cgit_print_http_headers();
75         html_include(path);
76 }
77
78 void cgit_clone_info(void)
79 {
80         if (!ctx.qry.path || strcmp(ctx.qry.path, "refs")) {
81                 cgit_print_error_page(400, "Bad request", "Bad request");
82                 return;
83         }
84
85         ctx.page.mimetype = "text/plain";
86         ctx.page.filename = "info/refs";
87         cgit_print_http_headers();
88         for_each_ref(print_ref_info, NULL);
89 }
90
91 void cgit_clone_objects(void)
92 {
93         if (!ctx.qry.path) {
94                 cgit_print_error_page(400, "Bad request", "Bad request");
95                 return;
96         }
97
98         if (!strcmp(ctx.qry.path, "info/packs")) {
99                 print_pack_info();
100                 return;
101         }
102
103         send_file(git_path("objects/%s", ctx.qry.path));
104 }
105
106 void cgit_clone_head(void)
107 {
108         send_file(git_path("%s", "HEAD"));
109 }