Example #1
0
function getJar() {
    var jar = new CookieJar();

    if (document.cookie && document.cookie.length) {
        var ca = document.cookie.split(';');
        var cValue;

        for (var i = 0; i < ca.length; i++) {
             cValue = ca[i];

            while (cValue.charAt(0) == ' ') cValue = cValue.substring(1);

            jar.setCookies(cValue, accessInfo);            
        }
    }

    return jar;
}
Example #2
0
 .forEach(cookieStr => {
   const cookie = new Cookie(cookieStr);
   if (!cookie.domain) {
     cookie.domain = domain;
   }
   if (!cookie.path) {
     cookie.path = path;
   }
   cookieJar.setCookie(cookie);
 });
Example #3
0
    requestCookies = uri => {
      const parsedURI = new URL(uri),
        domain = parsedURI.hostname,
        path = parsedURI.pathname,
        secure = parsedURI.protocol === 'https:',
        script = false,
        accessInfo = new CookieAccessInfo(domain, path, secure, script),
        cookies = cookieJar.getCookies(accessInfo);

      return cookies && cookies.map(cookie => cookie.toValueString());
    },
Example #4
0
Request.prototype.request = function(){
  if (this.req) return this.req;

  const options = {};

  try {
    const query = qs.stringify(this.qs, {
      indices: false,
      strictNullHandling: true,
    });
    if (query) {
      this.qs = {};
      this._query.push(query);
    }
    this._finalizeQueryString();
  } catch (e) {
    return this.emit('error', e);
  }

  let url = this.url;
  const retries = this._retries;

  // Capture backticks as-is from the final query string built above.
  // Note: this'll only find backticks entered in req.query(String)
  // calls, because qs.stringify unconditionally encodes backticks.
  let queryStringBackticks;
  if(url.indexOf('`') > -1) {
    const queryStartIndex = url.indexOf("?");

    if(queryStartIndex !== -1) {
      const queryString = url.substr(queryStartIndex + 1);
      queryStringBackticks = queryString.match(/`|\%60/g);
    }
  }

  // default to http://
  if (0 != url.indexOf('http')) url = `http://${url}`;
  url = parse(url);

  // See https://github.com/visionmedia/superagent/issues/1367
  if(queryStringBackticks) {
    let i = 0;
    url.query = url.query.replace(/\%60/g, () => queryStringBackticks[i++]);
    url.search = `?${url.query}`;
    url.path = url.pathname + url.search;
  }

  // support unix sockets
  if (/^https?\+unix:/.test(url.protocol) === true) {
    // get the protocol
    url.protocol = `${url.protocol.split('+')[0]}:`;

    // get the socket, path
    const unixParts = url.path.match(/^([^/]+)(.+)$/);
    options.socketPath = unixParts[1].replace(/%2F/g, '/');
    url.path = unixParts[2];
  }

  // options
  options.method = this.method;
  options.port = url.port;
  options.path = url.path;
  options.host = url.hostname;
  options.ca = this._ca;
  options.key = this._key;
  options.pfx = this._pfx;
  options.cert = this._cert;
  options.passphrase = this._passphrase;
  options.agent = this._agent;

  // Allows request.get('https://1.2.3.4/').set('Host', 'example.com')
  if (this._header['host']) {
    options.servername = this._header['host'].replace(/:[0-9]+$/,'');
  }

  // initiate request
  const mod = this._enableHttp2 ? exports.protocols['http2:'].setProtocol(url.protocol) : exports.protocols[url.protocol];

  // request
  const req = (this.req = mod.request(options));

  // set tcp no delay
  req.setNoDelay(true);

  if ('HEAD' != options.method) {
    req.setHeader('Accept-Encoding', 'gzip, deflate');
  }
  this.protocol = url.protocol;
  this.host = url.host;

  // expose events
  req.once('drain', () => { this.emit('drain'); });

  req.on('error', err => {
    // flag abortion here for out timeouts
    // because node will emit a faux-error "socket hang up"
    // when request is aborted before a connection is made
    if (this._aborted) return;
    // if not the same, we are in the **old** (cancelled) request,
    // so need to continue (same as for above)
    if (this._retries !== retries) return;
    // if we've received a response then we don't want to let
    // an error in the request blow up the response
    if (this.response) return;
    this.callback(err);
  });

  // auth
  if (url.auth) {
    const auth = url.auth.split(':');
    this.auth(auth[0], auth[1]);
  }
  if (this.username && this.password) {
    this.auth(this.username, this.password);
  }
  for (const key in this.header) {
    if (this.header.hasOwnProperty(key))
      req.setHeader(key, this.header[key]);
  }

  // add cookies
  if (this.cookies) {
    if(this._header.hasOwnProperty('cookie')) {
      // merge
      const tmpJar = new CookieJar.CookieJar();
      tmpJar.setCookies(this._header.cookie.split(';'));
      tmpJar.setCookies(this.cookies.split(';'));
      req.setHeader('Cookie',tmpJar.getCookies(CookieJar.CookieAccessInfo.All).toValueString());
    } else {
      req.setHeader('Cookie', this.cookies);
    }
  }

  return req;
};
Example #5
0
 setCookie = cookie => cookieJar.setCookie(cookie),
Example #6
0
 getCookies = ({domain, path = '/', secure = true, script = false}) =>
   cookieJar.getCookies(new CookieAccessInfo(domain, path, secure, script)),
Example #7
0
newAgent = () => {
  let logPages = true,
    logDir,
    userAgent = USER_AGENTS.Mechanize;

  const history = newHistory(),
    cookieJar = new CookieJar(),

    addResponseCookie = ({cookieString, domain, path}) => {
      const cookieStringSplitter = /[:](?=\s*[a-zA-Z0-9_-]+\s*[=])/g;
      cookieString
        .split(cookieStringSplitter)
        .forEach(cookieStr => {
          const cookie = new Cookie(cookieStr);
          if (!cookie.domain) {
            cookie.domain = domain;
          }
          if (!cookie.path) {
            cookie.path = path;
          }
          cookieJar.setCookie(cookie);
        });
    },

    addResponseCookies = ({response, uri, page}) => {
      const domain = uri.hostname,
        path = uri.pathname;

      page.search('//head/meta[@http-equiv="Set-Cookie"]')
        .forEach(meta => {
          if (meta.attr('content') && meta.attr('content').value()) {
            addResponseCookie({
              cookieString: meta.attr('content').value(),
              domain,
              path
            });
          }
        });

      let cookieHeaders =
              response.headers && response.headers['set-cookie'] || [];
      if (!Array.isArray(cookieHeaders)) {
        cookieHeaders = [cookieHeaders];
      }
      cookieHeaders.forEach(header => {
        if (header) {
          addResponseCookie({cookieString: header, domain, path});
        }
      });
    },

    requestHeaders = options => {
      const headers = {
        'User-Agent': userAgent,
        Accept: '*/*'
      },
        referer = options.referer || history.currentPage() ||
              newPage({response: {'content-type': 'text/html'}, agent});


      Object.assign(headers, options.headers);

      let refererURI;
      if (typeof (referer) === 'string') {
        refererURI = referer;
      } else if (referer) {
        refererURI = referer.uri;
      }

      if (refererURI) {
        const parsedURI = new URL(refererURI);

        headers.Referer = refererURI;
        headers.Origin = parsedURI.protocol + '//' + parsedURI.host;
      }

      return headers;
    },

    requestCookies = uri => {
      const parsedURI = new URL(uri),
        domain = parsedURI.hostname,
        path = parsedURI.pathname,
        secure = parsedURI.protocol === 'https:',
        script = false,
        accessInfo = new CookieAccessInfo(domain, path, secure, script),
        cookies = cookieJar.getCookies(accessInfo);

      return cookies && cookies.map(cookie => cookie.toValueString());
    },

    getCookieString = uri => {
      const cookies = requestCookies(uri);
      return cookies && cookies.join('; ');
    },

    requestOptions = options => {
      // uri
      // baseUrl
      // method
      // headers
      // qs
      // qsParseOptions
      // qsStringifyOptions
      // useQuerystring
      // body
      // form
      // formData
      // multipart
      // preambleCRLF
      // postambleCRLF
      // json
      // jsonReviver
      // jsonReplacer
      // auth
      // oauth
      // hawk
      // aws
      // httpSignature
      // followRedirect
      // followAllRedirects
      // followOriginalHttpMethod
      // maxRedirects
      // removeRefererHeader
      // encoding
      // gzip
      // jar
      // agent
      // agentClass
      // agentOptions
      // forever
      // pool
      // timeout
      // localAddress
      // proxy
      // strictSSL
      // tunnel
      // proxyHeaderWhiteList
      // proxyHeaderExclusiveList
      // time
      // har
      const reqOptions = {
        headers: requestHeaders(options),
        body: options.body,
        followAllRedirects: options.followAllRedirects
      };
      if (reqOptions.headers.Referer) {
        reqOptions.uri =
          new URL(options.uri, reqOptions.headers.Referer).toString();
      } else {
        reqOptions.uri = options.uri.toString();
      }
      reqOptions.jar = cookieJar;
      reqOptions.method = options.verb && options.verb.toUpperCase() || 'GET';

      if (options.encoding !== 'undefined') {
        reqOptions.encoding = options.encoding;
      }
      reqOptions.encoding = null;
      reqOptions.resolveWithFullResponse = true;

      return reqOptions;
    },

    logPage = async ({body, uri, response}) => {
      const contentType = response.headers['content-type'],
        ext = mime.extension(contentType &&
                                 contentType.split(/[ \t]*;[ \t]*/)[0]),
        timestamp = moment.utc().format('YYYYMMDDHHmmssSSSSSS'),
        filename = path.join(
          logDir,
          timestamp + '_' +
            path.basename(uri, path.extname(uri))) +
              (ext ? '.' + ext : ''),
        encoding = 'utf8';

      await writeFile(filename, body, {encoding});
      return filename;
    },

    fetchPage = async options => {
      const reqOptions = requestOptions(options),
        uri = reqOptions.uri,
        response = await request(reqOptions);

      if (reqOptions.encoding === null) {
        const body = response.body;
        if (body[0] === 0xEF && body[1] === 0xBB && body[2] === 0xBF) {
          // UTF-8
          const body2 = Buffer.allocUnsafe(body.length - 3);
          body.copy(body2, 0, 3);
          response.body = body2.toString('utf8');
        } else if (body[0] === 0xFE && body[1] === 0xFF) {
          // UTF-16 big-endian
          body.swap16();
          const body2 = Buffer.allocUnsafe(body.length - 2);
          body.copy(body2, 0, 2);
          response.body = body2.toString('utf16le');
        } else if (body[0] === 0xFF && body[1] === 0xFE) {
          // UTF-16 little-endian
          const body2 = Buffer.allocUnsafe(body.length - 2);
          body.copy(body2, 0, 2);
          response.body = body2.toString('utf16le');
        } else {
          // UTF-8
          response.body = body.toString('binary');
        }
      }
      if (options.fixCharset) {
        response.body = response.body.replace('charset=utf-16le', 'utf-8');
        if (response.body.match(/charset=windows-1252/)) {
          response.body = windows1252.decode(response.body);
        }
      }
      const page = newPage({
        uri,
        response,
        body: response.body,
        code: response.statusCode,
        agent
      });

      addResponseCookies({
        response,
        uri: new URL(uri),
        page
      });
      history.push(page);
      if (logPages && logDir) {
        await logPage({body: response.body, uri, response});
      }
      return page;
    },

    submit = ({form, button, headers, followAllRedirects}) => {
      const action = button && button.action || form.action || '',
        enctype = button && button.enctype || form.enctype,
        method = button && button.method || form.method;
      let verb, params, body,
        uri = action && querystring.unescape(action) ||
            form.page && form.page.uri,
        contentType = enctype, requestHeaders = {};

      if (button) {
        form.addButtonToQuery(button);
      }
      if (method && method.toLowerCase() === 'post') {
        if (contentType === 'multipart/form-data') {
          contentType += '; boundary=' + form.boundary;
        }
        verb = 'post';
        body = form.requestData(enctype);
        requestHeaders = {
          'Content-Type': contentType,
          'Content-Length': body.length.toString()
        };
      } else {
        verb = 'get';
        uri = uri.replace(/\?[!#$&-;=?-[\]_a-z~]*$/, '');
        params = form.buildQuery();
      }

      return fetchPage({
        verb,
        uri,
        headers: Object.assign(requestHeaders, headers),
        referer: form.page,
        followAllRedirects,
        params,
        body
      });
    },

    setUserAgent = agentAlias => userAgent = USER_AGENTS[agentAlias],

    getCookies = ({domain, path = '/', secure = true, script = false}) =>
      cookieJar.getCookies(new CookieAccessInfo(domain, path, secure, script)),

    setCookie = cookie => cookieJar.setCookie(cookie),

    agent = {
      get: fetchPage,
      getCookies,
      setCookie,
      setUserAgent,
      submit,
      userAgent: () => userAgent
    };

  cookieJar.getCookieString = getCookieString;
  return Object.freeze(agent);
};