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);
+}
* 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
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);
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;
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;
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)
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;
/* 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;
/* 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;
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;
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;
/* 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;
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;