@@ -1614,14 +1614,136 @@ bool setCacheKey(JSContext *cx, unsigned argc, Value *vp) {
1614
1614
args.rval ().setUndefined ();
1615
1615
return true ;
1616
1616
}
1617
+ JSString *GET_atom;
1618
+ JSObject *create_instance (JSContext *cx);
1619
+ JSObject *create (JSContext *cx, HandleObject requestInstance, HandleValue input,
1620
+ HandleValue init_val);
1621
+
1622
+ bool clone (JSContext *cx, unsigned argc, Value *vp) {
1623
+ METHOD_HEADER (0 )
1624
+
1625
+ if (RequestOrResponse::body_used (self)) {
1626
+ JS_ReportErrorLatin1 (cx, " Request.prototype.clone: the request's body isn't usable." );
1627
+ return false ;
1628
+ }
1629
+
1630
+ // Here we get the current requests body stream and call ReadableStream.prototype.tee to return
1631
+ // two versions of the stream. Once we get the two streams, we create a new request handle and
1632
+ // attach one of the streams to the new handle and the other stream is attached to the request
1633
+ // handle that `clone()` was called upon.
1634
+ RootedObject body_stream (cx, ::RequestOrResponse::body_stream (self));
1635
+ if (!body_stream) {
1636
+ body_stream = ::RequestOrResponse::create_body_stream (cx, self);
1637
+ if (!body_stream) {
1638
+ return false ;
1639
+ }
1640
+ }
1641
+ RootedValue tee_val (cx);
1642
+ if (!JS_GetProperty (cx, body_stream, " tee" , &tee_val)) {
1643
+ return false ;
1644
+ }
1645
+ JS::Rooted<JSFunction *> tee (cx, JS_GetObjectFunction (&tee_val.toObject ()));
1646
+ if (!tee) {
1647
+ return false ;
1648
+ }
1649
+ JS::RootedVector<JS::Value> argv (cx);
1650
+ RootedValue rval (cx);
1651
+ if (!JS::Call (cx, body_stream, tee, argv, &rval)) {
1652
+ return false ;
1653
+ }
1654
+ RootedObject rval_array (cx, &rval.toObject ());
1655
+ RootedValue body1_val (cx);
1656
+ if (!JS_GetProperty (cx, rval_array, " 0" , &body1_val)) {
1657
+ return false ;
1658
+ }
1659
+ RootedValue body2_val (cx);
1660
+ if (!JS_GetProperty (cx, rval_array, " 1" , &body2_val)) {
1661
+ return false ;
1662
+ }
1663
+
1664
+ fastly_error_t err;
1665
+ fastly_request_handle_t request_handle = INVALID_HANDLE;
1666
+ if (!xqd_fastly_http_req_new (&request_handle, &err)) {
1667
+ HANDLE_ERROR (cx, err);
1668
+ return false ;
1669
+ }
1670
+
1671
+ fastly_body_handle_t body_handle = INVALID_HANDLE;
1672
+ if (!xqd_fastly_http_body_new (&body_handle, &err)) {
1673
+ HANDLE_ERROR (cx, err);
1674
+ return false ;
1675
+ }
1676
+
1677
+ if (!JS::IsReadableStream (&body1_val.toObject ())) {
1678
+ return false ;
1679
+ }
1680
+ body_stream.set (&body1_val.toObject ());
1681
+ if (RequestOrResponse::body_unusable (cx, body_stream)) {
1682
+ JS_ReportErrorLatin1 (cx, " Can't use a ReadableStream that's locked or has ever been "
1683
+ " read from or canceled as a Request body." );
1684
+ return false ;
1685
+ }
1686
+
1687
+ RootedObject requestInstance (cx, create_instance (cx));
1688
+ JS::SetReservedSlot (requestInstance, Slots::Request, JS::Int32Value (request_handle));
1689
+ JS::SetReservedSlot (requestInstance, Slots::Body, JS::Int32Value (body_handle));
1690
+ JS::SetReservedSlot (requestInstance, Slots::BodyStream, body1_val);
1691
+ JS::SetReservedSlot (requestInstance, Slots::BodyUsed, JS::FalseValue ());
1692
+ JS::SetReservedSlot (requestInstance, Slots::HasBody, JS::BooleanValue (true ));
1693
+ JS::SetReservedSlot (requestInstance, Slots::URL, JS::GetReservedSlot (self, Slots::URL));
1694
+ JS::SetReservedSlot (requestInstance, Slots::IsDownstream,
1695
+ JS::GetReservedSlot (self, Slots::IsDownstream));
1696
+
1697
+ JS::SetReservedSlot (self, Slots::BodyStream, body2_val);
1698
+ JS::SetReservedSlot (self, Slots::BodyUsed, JS::FalseValue ());
1699
+ JS::SetReservedSlot (self, Slots::HasBody, JS::BooleanValue (true ));
1700
+
1701
+ RootedObject headers (cx);
1702
+ RootedObject headers_obj (cx, RequestOrResponse::headers<Headers::Mode::ProxyToRequest>(cx, self));
1703
+ if (!headers_obj) {
1704
+ return false ;
1705
+ }
1706
+ RootedObject headersInstance (
1707
+ cx, JS_NewObjectWithGivenProto (cx, &Headers::class_, Headers::proto_obj));
1708
+ if (!headersInstance)
1709
+ return false ;
1710
+
1711
+ headers = Headers::create (cx, headersInstance, Headers::Mode::ProxyToRequest, requestInstance,
1712
+ headers_obj);
1713
+
1714
+ if (!headers) {
1715
+ return false ;
1716
+ }
1717
+
1718
+ JS::SetReservedSlot (requestInstance, Slots::Headers, JS::ObjectValue (*headers));
1719
+
1720
+ JSString *method = Request::method (cx, self);
1721
+ if (!method) {
1722
+ return false ;
1723
+ }
1724
+
1725
+ JS::SetReservedSlot (requestInstance, Slots::Method, JS::StringValue (method));
1726
+ RootedValue cache_override (cx, JS::GetReservedSlot (self, Slots::CacheOverride));
1727
+ if (!cache_override.isNullOrUndefined ()) {
1728
+ if (!set_cache_override (cx, requestInstance, cache_override)) {
1729
+ return false ;
1730
+ }
1731
+ } else {
1732
+ JS::SetReservedSlot (requestInstance, Slots::CacheOverride, cache_override);
1733
+ }
1734
+
1735
+ args.rval ().setObject (*requestInstance);
1736
+ return true ;
1737
+ }
1617
1738
1618
1739
const JSFunctionSpec methods[] = {
1619
1740
JS_FN (" arrayBuffer" , bodyAll<RequestOrResponse::BodyReadResult::ArrayBuffer>, 0 ,
1620
1741
JSPROP_ENUMERATE),
1621
1742
JS_FN (" json" , bodyAll<RequestOrResponse::BodyReadResult::JSON>, 0 , JSPROP_ENUMERATE),
1622
1743
JS_FN (" text" , bodyAll<RequestOrResponse::BodyReadResult::Text>, 0 , JSPROP_ENUMERATE),
1623
1744
JS_FN (" setCacheOverride" , setCacheOverride, 3 , JSPROP_ENUMERATE),
1624
- JS_FN (" setCacheKey" , setCacheKey, 3 , JSPROP_ENUMERATE),
1745
+ JS_FN (" setCacheKey" , setCacheKey, 0 , JSPROP_ENUMERATE),
1746
+ JS_FN (" clone" , clone, 0 , JSPROP_ENUMERATE),
1625
1747
JS_FS_END};
1626
1748
1627
1749
const JSPropertySpec properties[] = {JS_PSG (" method" , method_get, JSPROP_ENUMERATE),
@@ -1637,8 +1759,6 @@ bool constructor(JSContext *cx, unsigned argc, Value *vp);
1637
1759
1638
1760
CLASS_BOILERPLATE_CUSTOM_INIT (Request)
1639
1761
1640
- JSString *GET_atom;
1641
-
1642
1762
bool init_class (JSContext *cx, HandleObject global) {
1643
1763
if (!init_class_impl (cx, global)) {
1644
1764
return false ;
@@ -2132,6 +2252,12 @@ JSObject *create(JSContext *cx, HandleObject requestInstance, HandleValue input,
2132
2252
return request;
2133
2253
}
2134
2254
2255
+ JSObject *create_instance (JSContext *cx) {
2256
+ RootedObject requestInstance (
2257
+ cx, JS_NewObjectWithGivenProto (cx, &Request::class_, Request::proto_obj));
2258
+ return requestInstance;
2259
+ }
2260
+
2135
2261
bool constructor (JSContext *cx, unsigned argc, Value *vp) {
2136
2262
REQUEST_HANDLER_ONLY (" The Request builtin" );
2137
2263
CTOR_HEADER (" Request" , 1 );
0 commit comments