REORG: http: move http_get_path() to http.c
This function is purely HTTP once http_txn is put aside. So the original
one was renamed to http_txn_get_path() and it extracts the relevant offsets
from the txn to pass them to http_get_path(). One benefit of the new version
is that it returns the length at the same time so that allowed to slightly
simplify http_get_path_from_string() which had to look up the end pointer
previously and which is not needed anymore.
diff --git a/include/common/http.h b/include/common/http.h
index d283e29..4184a47 100644
--- a/include/common/http.h
+++ b/include/common/http.h
@@ -114,6 +114,7 @@
extern const char *HTTP_303;
enum http_meth_t find_http_meth(const char *str, const int len);
+struct ist http_get_path(const struct ist uri);
#endif /* _COMMON_HTTP_H */
diff --git a/include/proto/proto_http.h b/include/proto/proto_http.h
index b537d45..9eba144 100644
--- a/include/proto/proto_http.h
+++ b/include/proto/proto_http.h
@@ -100,7 +100,7 @@
unsigned int http_get_hdr(const struct http_msg *msg, const char *hname, int hlen,
struct hdr_idx *idx, int occ,
struct hdr_ctx *ctx, char **vptr, size_t *vlen);
-char *http_get_path(struct http_txn *txn);
+char *http_txn_get_path(const struct http_txn *txn);
const char *get_reason(unsigned int status);
struct http_txn *http_alloc_txn(struct stream *s);
diff --git a/src/cache.c b/src/cache.c
index f58c3cc..3abb46c 100644
--- a/src/cache.c
+++ b/src/cache.c
@@ -650,7 +650,7 @@
/* now retrieve the path */
end = ci_head(txn->req.chn) + txn->req.sl.rq.u + txn->req.sl.rq.u_l;
- path = http_get_path(txn);
+ path = http_txn_get_path(txn);
if (!path)
return 0;
chunk_strncat(trash, path, end - path);
diff --git a/src/hlua.c b/src/hlua.c
index f07df47..6f001d5 100644
--- a/src/hlua.c
+++ b/src/hlua.c
@@ -3945,7 +3945,7 @@
lua_settable(L, -3);
/* Get path and qs */
- path = http_get_path(txn);
+ path = http_txn_get_path(txn);
if (path) {
end = ci_head(txn->req.chn) + txn->req.sl.rq.u + txn->req.sl.rq.u_l;
p = path;
diff --git a/src/http.c b/src/http.c
index ad620a9..66a91db 100644
--- a/src/http.c
+++ b/src/http.c
@@ -183,3 +183,53 @@
else if (isteq(m, ist("TRACE"))) return HTTP_METH_TRACE;
else return HTTP_METH_OTHER;
}
+
+/* Parse the URI from the given transaction (which is assumed to be in request
+ * phase) and look for the "/" beginning the PATH. If not found, ist2(0,0) is
+ * returned. Otherwise the pointer and length are returned.
+ */
+struct ist http_get_path(const struct ist uri)
+{
+ const char *ptr, *end;
+
+ if (!uri.len)
+ goto not_found;
+
+ ptr = uri.ptr;
+ end = ptr + uri.len;
+
+ /* RFC7230, par. 2.7 :
+ * Request-URI = "*" | absuri | abspath | authority
+ */
+
+ if (*ptr == '*')
+ goto not_found;
+
+ if (isalpha((unsigned char)*ptr)) {
+ /* this is a scheme as described by RFC3986, par. 3.1 */
+ ptr++;
+ while (ptr < end &&
+ (isalnum((unsigned char)*ptr) || *ptr == '+' || *ptr == '-' || *ptr == '.'))
+ ptr++;
+ /* skip '://' */
+ if (ptr == end || *ptr++ != ':')
+ goto not_found;
+ if (ptr == end || *ptr++ != '/')
+ goto not_found;
+ if (ptr == end || *ptr++ != '/')
+ goto not_found;
+ }
+ /* skip [user[:passwd]@]host[:[port]] */
+
+ while (ptr < end && *ptr != '/')
+ ptr++;
+
+ if (ptr == end)
+ goto not_found;
+
+ /* OK, we got the '/' ! */
+ return ist2(ptr, end - ptr);
+
+ not_found:
+ return ist2(NULL, 0);
+}
diff --git a/src/proto_http.c b/src/proto_http.c
index b153b14..047e270 100644
--- a/src/proto_http.c
+++ b/src/proto_http.c
@@ -914,87 +914,13 @@
* phase) and look for the "/" beginning the PATH. If not found, return NULL.
* It is returned otherwise.
*/
-char *http_get_path(struct http_txn *txn)
+char *http_txn_get_path(const struct http_txn *txn)
{
- char *ptr, *end;
-
- ptr = ci_head(txn->req.chn) + txn->req.sl.rq.u;
- end = ptr + txn->req.sl.rq.u_l;
-
- if (ptr >= end)
- return NULL;
-
- /* RFC7230, par. 2.7 :
- * Request-URI = "*" | absuri | abspath | authority
- */
-
- if (*ptr == '*')
- return NULL;
-
- if (isalpha((unsigned char)*ptr)) {
- /* this is a scheme as described by RFC3986, par. 3.1 */
- ptr++;
- while (ptr < end &&
- (isalnum((unsigned char)*ptr) || *ptr == '+' || *ptr == '-' || *ptr == '.'))
- ptr++;
- /* skip '://' */
- if (ptr == end || *ptr++ != ':')
- return NULL;
- if (ptr == end || *ptr++ != '/')
- return NULL;
- if (ptr == end || *ptr++ != '/')
- return NULL;
- }
- /* skip [user[:passwd]@]host[:[port]] */
-
- while (ptr < end && *ptr != '/')
- ptr++;
-
- if (ptr == end)
- return NULL;
-
- /* OK, we got the '/' ! */
- return ptr;
-}
+ struct ist ret;
-/* Parse the URI from the given string and look for the "/" beginning the PATH.
- * If not found, return NULL. It is returned otherwise.
- */
-static char *
-http_get_path_from_string(char *str)
-{
- char *ptr = str;
-
- /* RFC2616, par. 5.1.2 :
- * Request-URI = "*" | absuri | abspath | authority
- */
-
- if (*ptr == '*')
- return NULL;
-
- if (isalpha((unsigned char)*ptr)) {
- /* this is a scheme as described by RFC3986, par. 3.1 */
- ptr++;
- while (isalnum((unsigned char)*ptr) || *ptr == '+' || *ptr == '-' || *ptr == '.')
- ptr++;
- /* skip '://' */
- if (*ptr == '\0' || *ptr++ != ':')
- return NULL;
- if (*ptr == '\0' || *ptr++ != '/')
- return NULL;
- if (*ptr == '\0' || *ptr++ != '/')
- return NULL;
- }
- /* skip [user[:passwd]@]host[:[port]] */
+ ret = http_get_path(ist2(ci_head(txn->req.chn) + txn->req.sl.rq.u, txn->req.sl.rq.u_l));
- while (*ptr != '\0' && *ptr != ' ' && *ptr != '/')
- ptr++;
-
- if (*ptr == '\0' || *ptr == ' ')
- return NULL;
-
- /* OK, we got the '/' ! */
- return ptr;
+ return ret.ptr;
}
/* Returns a 302 for a redirectable request that reaches a server working in
@@ -1032,7 +958,7 @@
txn = s->txn;
c_rew(&s->req, rewind = http_hdr_rewind(&txn->req));
- path = http_get_path(txn);
+ path = http_txn_get_path(txn);
len = b_dist(&s->req.buf, path, c_ptr(&s->req, txn->req.sl.rq.u + txn->req.sl.rq.u_l));
c_adv(&s->req, rewind);
@@ -3159,7 +3085,7 @@
hostlen = ctx.vlen;
}
- path = http_get_path(txn);
+ path = http_txn_get_path(txn);
/* build message using path */
if (path) {
pathlen = req->sl.rq.u_l + (ci_head(req->chn) + req->sl.rq.u) - path;
@@ -3226,7 +3152,7 @@
const char *path;
int pathlen;
- path = http_get_path(txn);
+ path = http_txn_get_path(txn);
/* build message using path */
if (path) {
pathlen = req->sl.rq.u_l + (ci_head(req->chn) + req->sl.rq.u) - path;
@@ -3718,7 +3644,7 @@
return 0;
}
- path = http_get_path(txn);
+ path = http_txn_get_path(txn);
if (url2sa(ci_head(req) + msg->sl.rq.u,
path ? path - (ci_head(req) + msg->sl.rq.u) : msg->sl.rq.u_l,
&conn->addr.to, NULL) == -1)
@@ -10323,7 +10249,7 @@
txn = smp->strm->txn;
end = ci_head(txn->req.chn) + txn->req.sl.rq.u + txn->req.sl.rq.u_l;
- ptr = http_get_path(txn);
+ ptr = http_txn_get_path(txn);
if (!ptr)
return 0;
@@ -10370,7 +10296,7 @@
/* now retrieve the path */
end = ci_head(txn->req.chn) + txn->req.sl.rq.u + txn->req.sl.rq.u_l;
- beg = http_get_path(txn);
+ beg = http_txn_get_path(txn);
if (!beg)
beg = end;
@@ -10417,7 +10343,7 @@
/* now retrieve the path */
end = ci_head(txn->req.chn) + txn->req.sl.rq.u + txn->req.sl.rq.u_l;
- beg = http_get_path(txn);
+ beg = http_txn_get_path(txn);
if (!beg)
beg = end;
@@ -10758,9 +10684,9 @@
static int
smp_fetch_capture_req_uri(const struct arg *args, struct sample *smp, const char *kw, void *private)
{
- struct buffer *temp;
struct http_txn *txn = smp->strm->txn;
- char *ptr;
+ struct ist path;
+ const char *ptr;
if (!txn || !txn->uri)
return 0;
@@ -10775,15 +10701,12 @@
ptr++; /* skip the space */
- temp = get_trash_chunk();
- ptr = temp->area = http_get_path_from_string(ptr);
- if (!ptr)
+ path = http_get_path(ist(ptr));
+ if (!path.ptr)
return 0;
- while (*ptr != ' ' && *ptr != '\0') /* find space after URI */
- ptr++;
- smp->data.u.str = *temp;
- smp->data.u.str.data = ptr - temp->area;
+ smp->data.u.str.area = path.ptr;
+ smp->data.u.str.data = path.len;
smp->data.type = SMP_T_STR;
smp->flags = SMP_F_CONST;
@@ -11467,7 +11390,7 @@
/* now retrieve the path */
end = ci_head(txn->req.chn) + txn->req.sl.rq.u + txn->req.sl.rq.u_l;
- beg = http_get_path(txn);
+ beg = http_txn_get_path(txn);
if (!beg)
beg = end;
@@ -11895,7 +11818,7 @@
break;
case 1: // path
- cur_ptr = http_get_path(txn);
+ cur_ptr = http_txn_get_path(txn);
if (!cur_ptr)
cur_ptr = ci_head(&s->req) + txn->req.sl.rq.u;