Repository: yt-dlp/yt-dlp
File: yt_dlp/extractor/veoh.py (Python)

Code before:

    _TESTS = [
        {
            'url': 'https://www.veoh.com/users/valentinazoe',
            'info_dict': {
                'id': 'valentinazoe',
                'title': 'valentinazoe (Uploads)'
            },
            'playlist_mincount': 75
        },
        {
            'url': 'https://www.veoh.com/users/PiensaLibre',
            'info_dict': {
                'id': 'PiensaLibre',
                'title': 'PiensaLibre (Uploads)'
            },
            'playlist_mincount': 2
        }]

    _USERSINFO_ENDPOINT = 'https://www.veoh.com/users/published/videos'
    _VIDEO_BASEURL = 'https://www.veoh.com/watch/'

    def _get_authtoken(self, page, uploader=None):
        webpage = self._download_webpage(page, uploader)
        return self._search_regex(
            r'csrfToken: "(?P<token>[0-9a-zA-Z]{40})"', webpage,
            'request token', group='token')

    def _get_videos(self, uploader, authtoken=None):
        if authtoken is None:
            authtoken = self._get_authtoken(f'https://www.veoh.com/users/{uploader}', uploader)
        totalVids = 0
        for i in itertools.count():
            payload = json.dumps({'username': uploader, 'maxResults': 16, 'page': i + 1, 'requestName': 'userPage'}).encode('utf-8')
            headers = {
                'x-csrf-token': authtoken,
                'content-type': 'application/json;charset=UTF-8'
            }
            for retry in self.RetryManager():
                try:
                    response = self._download_json(
                        self._USERSINFO_ENDPOINT, uploader, data=payload, headers=headers,
                        note=f'Downloading videos page {i + 1}')
                    if not response['success']:
                        raise ExtractorError('unsuccessful veoh user videos request')
                    break
                except ExtractorError as e:
                    raise e

            def resolve_entry(*candidates):
                for cand in candidates:

Review comment (security):
I'd relax the regex a little bit

```suggestion
            r'csrfToken:\s*(["\'])(?P<token>[0-9a-zA-Z]{40})\1', webpage,
```
is the csrf token always 40 characters long?

Code after:
        {
            'url': 'https://www.veoh.com/users/valentinazoe',
            'info_dict': {
                'id': 'valentinazoe',
                'title': 'valentinazoe (Uploads)'
            },
            'playlist_mincount': 75
        },
        {
            'url': 'https://www.veoh.com/users/PiensaLibre',
            'info_dict': {
                'id': 'PiensaLibre',
                'title': 'PiensaLibre (Uploads)'
            },
            'playlist_mincount': 2
        }]

    _PAGE_SIZE = 16

    def _fetch_page(self, uploader, page):
        response = self._download_json(
            'https://www.veoh.com/users/published/videos', uploader,
            note=f'Downloading videos page {page + 1}',
            headers={
                'x-csrf-token': self._TOKEN,
                'content-type': 'application/json;charset=UTF-8'
            },
            data=json.dumps({
                'username': uploader,
                'maxResults': self._PAGE_SIZE,
                'page': page + 1,
                'requestName': 'userPage'
            }).encode('utf-8'))
        if not response.get('success'):
            raise ExtractorError(response['message'])

        for video in response['videos']:
            yield self.url_result(f'https://www.veoh.com/watch/{video["permalinkId"]}', VeohIE,
                                  video['permalinkId'], video.get('title'))

    def _real_initialize(self):
        webpage = self._download_webpage(
            'https://www.veoh.com', None, note='Downloading authorization token')
        self._TOKEN = self._search_regex(
            r'csrfToken:\s*(["\'])(?P<token>[0-9a-zA-Z]{40})\1', webpage,
            'request token', group='token')

    def _real_extract(self, url):
        uploader = self._match_id(url)
        return self.playlist_result(OnDemandPagedList(
            functools.partial(self._fetch_page, uploader),