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