|
1 | 1 | #define USE_THE_REPOSITORY_VARIABLE
|
2 | 2 | #include "git-compat-util.h"
|
3 | 3 | #include "environment.h"
|
| 4 | +#include "gettext.h" |
4 | 5 | #include "hex.h"
|
5 | 6 | #include "alloc.h"
|
6 | 7 | #include "setup.h"
|
@@ -1500,6 +1501,8 @@ static enum worker_result req__read(struct req *req, int fd)
|
1500 | 1501 |
|
1501 | 1502 | static enum worker_result dispatch(struct req *req)
|
1502 | 1503 | {
|
| 1504 | + static regex_t *smart_http_regex; |
| 1505 | + static int initialized; |
1503 | 1506 | const char *method;
|
1504 | 1507 | enum worker_result wr;
|
1505 | 1508 |
|
@@ -1548,6 +1551,54 @@ static enum worker_result dispatch(struct req *req)
|
1548 | 1551 | return do__gvfs_prefetch__get(req);
|
1549 | 1552 | }
|
1550 | 1553 |
|
| 1554 | + if (!initialized) { |
| 1555 | + smart_http_regex = xmalloc(sizeof(*smart_http_regex)); |
| 1556 | + if (regcomp(smart_http_regex, "^/(HEAD|info/refs|" |
| 1557 | + "objects/info/[^/]+|git-(upload|receive)-pack)$", |
| 1558 | + REG_EXTENDED)) { |
| 1559 | + warning("could not compile smart HTTP regex"); |
| 1560 | + smart_http_regex = NULL; |
| 1561 | + } |
| 1562 | + initialized = 1; |
| 1563 | + } |
| 1564 | + |
| 1565 | + if (smart_http_regex && |
| 1566 | + !regexec(smart_http_regex, req->uri_base.buf, 0, NULL, 0)) { |
| 1567 | + const char *ok = "HTTP/1.1 200 OK\r\n"; |
| 1568 | + struct child_process cp = CHILD_PROCESS_INIT; |
| 1569 | + size_t i; |
| 1570 | + int res; |
| 1571 | + |
| 1572 | + if (write(1, ok, strlen(ok)) < 0) |
| 1573 | + return error(_("could not send '%s'"), ok); |
| 1574 | + |
| 1575 | + strvec_pushf(&cp.env, "REQUEST_METHOD=%s", method); |
| 1576 | + strvec_pushf(&cp.env, "PATH_TRANSLATED=%s", |
| 1577 | + req->uri_base.buf); |
| 1578 | + /* Prevent MSYS2 from "converting to a Windows path" */ |
| 1579 | + strvec_pushf(&cp.env, |
| 1580 | + "MSYS2_ENV_CONV_EXCL=PATH_TRANSLATED"); |
| 1581 | + strvec_push(&cp.env, "SERVER_PROTOCOL=HTTP/1.1"); |
| 1582 | + if (req->quest_args.len) |
| 1583 | + strvec_pushf(&cp.env, "QUERY_STRING=%s", |
| 1584 | + req->quest_args.buf); |
| 1585 | + for (i = 0; i < req->header_list.nr; i++) { |
| 1586 | + const char *header = req->header_list.items[i].string; |
| 1587 | + if (!strncasecmp("Content-Type: ", header, 14)) |
| 1588 | + strvec_pushf(&cp.env, "CONTENT_TYPE=%s", |
| 1589 | + header + 14); |
| 1590 | + else if (!strncasecmp("Content-Length: ", header, 16)) |
| 1591 | + strvec_pushf(&cp.env, "CONTENT_LENGTH=%s", |
| 1592 | + header + 16); |
| 1593 | + } |
| 1594 | + cp.git_cmd = 1; |
| 1595 | + strvec_push(&cp.args, "http-backend"); |
| 1596 | + res = run_command(&cp); |
| 1597 | + close(1); |
| 1598 | + close(0); |
| 1599 | + return !!res; |
| 1600 | + } |
| 1601 | + |
1551 | 1602 | return send_http_error(1, 501, "Not Implemented", -1,
|
1552 | 1603 | WR_OK | WR_HANGUP);
|
1553 | 1604 | }
|
|
0 commit comments