Browse Source

Premium file endpoints

master
Eduard Kuzmenko 2 years ago
parent
commit
aa9ae81a32
  1. 4
      src/lib/mtproto/apiFileManager.ts
  2. 70
      src/lib/mtproto/apiManager.ts
  3. 32
      src/lib/mtproto/dcConfigurator.ts
  4. 9
      src/lib/mtproto/transports/tcpObfuscated.ts

4
src/lib/mtproto/apiFileManager.ts

@ -234,14 +234,14 @@ export class ApiFileManager extends AppManager { @@ -234,14 +234,14 @@ export class ApiFileManager extends AppManager {
const invoke = async(): Promise<MyUploadFile> => {
checkCancel && checkCancel(); // do not remove async, because checkCancel will throw an error
const promise = this.apiManager.invokeApi('upload.getFile', {
const promise = /* pause(1000).then(() => */this.apiManager.invokeApi('upload.getFile', {
location,
offset,
limit
}, {
dcId,
fileDownload: true
}) as Promise<MyUploadFile>;
}) as Promise<MyUploadFile>/* ) */;
return promise.catch((err) => {
if(err.type === 'FILE_REFERENCE_EXPIRED') {

70
src/lib/mtproto/apiManager.ts

@ -9,10 +9,6 @@ @@ -9,10 +9,6 @@
* https://github.com/zhukov/webogram/blob/master/LICENSE
*/
/// #if !MTPROTO_WORKER
import rootScope from '../rootScope';
/// #endif
/// #if MTPROTO_AUTO
import transportController from './transports/controller';
import MTTransport from './transports/transport';
@ -21,16 +17,14 @@ import MTTransport from './transports/transport'; @@ -21,16 +17,14 @@ import MTTransport from './transports/transport';
import type { UserAuth } from './mtproto_config';
import sessionStorage from '../sessionStorage';
import MTPNetworker, { MTMessage } from './networker';
//import { telegramMeWebService } from './mtproto';
import { ConnectionType, DcConfigurator, TransportType } from './dcConfigurator';
import { ConnectionType, constructTelegramWebSocketUrl, DcConfigurator, TransportType } from './dcConfigurator';
import { logger } from '../logger';
import type { DcAuthKey, DcId, DcServerSalt, InvokeApiOptions } from '../../types';
import type { MethodDeclMap } from '../../layer';
import deferredPromise, { CancellablePromise } from '../../helpers/cancellablePromise';
//import { clamp } from '../../helpers/number';
import App from '../../config/app';
import { MOUNT_CLASS_TO } from '../../config/debug';
import IDBStorage, { IDB } from '../idb';
import { IDB } from '../idb';
import CryptoWorker from "../crypto/cryptoMessagePort";
import ctx from '../../environment/ctx';
import noop from '../../helpers/noop';
@ -41,21 +35,8 @@ import isObject from '../../helpers/object/isObject'; @@ -41,21 +35,8 @@ import isObject from '../../helpers/object/isObject';
import pause from '../../helpers/schedulers/pause';
import ApiManagerMethods from './api_methods';
import { getEnvironment } from '../../environment/utils';
import AppStorage from '../storage';
import toggleStorages from '../../helpers/toggleStorages';
/* var networker = apiManager.cachedNetworkers.websocket.upload[2];
networker.wrapMtpMessage({
_: 'msgs_state_req',
msg_ids: ["6888292542796810828"]
}, {
notContentRelated: true
}).then((res) => {
console.log('status', res);
}); */
//console.error('apiManager included!');
// TODO: если запрос словил флуд, нужно сохранять его параметры и возвращать тот же промис на новый такой же запрос, например - загрузка истории
import type TcpObfuscated from './transports/tcpObfuscated';
export type ApiError = Partial<{
code: number,
@ -137,6 +118,25 @@ export class ApiManager extends ApiManagerMethods { @@ -137,6 +118,25 @@ export class ApiManager extends ApiManagerMethods {
this.getAppConfig(true);
}
});
this.rootScope.addEventListener('premium_toggle', (isPremium) => {
this.iterateNetworkers(({networker, connectionType, dcId, transportType}) => {
if(connectionType === 'client' || transportType !== 'websocket') {
return;
}
const transport = networker.transport;
if(!transport) {
this.log.error('wow what, no transport?', networker);
return;
}
if((transport as TcpObfuscated).connection) {
const url = constructTelegramWebSocketUrl(dcId, connectionType, isPremium);
(transport as TcpObfuscated).changeUrl(url);
}
});
});
}
//private lol = false;
@ -348,7 +348,7 @@ export class ApiManager extends ApiManagerMethods { @@ -348,7 +348,7 @@ export class ApiManager extends ApiManagerMethods {
// @ts-ignore
const maxNetworkers = connectionType === 'client' || transportType === 'https' ? 1 : (this.rootScope.premium ? PREMIUM_FILE_NETWORKERS_COUNT : REGULAR_FILE_NETWORKERS_COUNT);
if(networkers.length >= maxNetworkers) {
let i = networkers.length - 1, found = false;
let i = maxNetworkers - 1, found = false;
for(; i >= 0; --i) {
if(networkers[i].isOnline) {
found = true;
@ -356,7 +356,7 @@ export class ApiManager extends ApiManagerMethods { @@ -356,7 +356,7 @@ export class ApiManager extends ApiManagerMethods {
}
}
const networker = found ? networkers.splice(i, 1)[0] : networkers.pop();
const networker = networkers.splice(found ? i : maxNetworkers - 1, 1)[0];
networkers.unshift(networker);
return Promise.resolve(networker);
}
@ -443,6 +443,15 @@ export class ApiManager extends ApiManagerMethods { @@ -443,6 +443,15 @@ export class ApiManager extends ApiManagerMethods {
networker.changeTransport(transport);
}
private onNetworkerDrain(networker: MTPNetworker) {
this.log('networker drain', networker.dcId);
networker.onDrain = undefined;
this.changeNetworkerTransport(networker);
networker.destroy();
this.networkerFactory.removeNetworker(networker);
DcConfigurator.removeTransport(this.cachedNetworkers, networker);
}
public setOnDrainIfNeeded(networker: MTPNetworker) {
if(networker.onDrain) {
return;
@ -457,16 +466,7 @@ export class ApiManager extends ApiManagerMethods { @@ -457,16 +466,7 @@ export class ApiManager extends ApiManagerMethods {
}
if(canRelease) {
networker.onDrain = () => {
this.log('networker drain', networker.dcId);
networker.onDrain = undefined;
this.changeNetworkerTransport(networker);
networker.destroy();
this.networkerFactory.removeNetworker(networker);
DcConfigurator.removeTransport(this.cachedNetworkers, networker);
};
networker.onDrain = () => this.onNetworkerDrain(networker);
networker.setDrainTimeout();
}
});
@ -645,7 +645,7 @@ export class ApiManager extends ApiManagerMethods { @@ -645,7 +645,7 @@ export class ApiManager extends ApiManagerMethods {
options.waitTime = options.waitTime ? Math.min(60, options.waitTime * 1.5) : 1;
return pause(options.waitTime * 1000).then(() => performRequest());
} else if(error.type === 'UNKNOWN') {
} else if(error.type === 'UNKNOWN' || error.type === 'MTPROTO_CLUSTER_INVALID') { // cluster invalid - request from regular user to premium endpoint
return pause(1000).then(() => performRequest());
} else {
throw error;

32
src/lib/mtproto/dcConfigurator.ts

@ -44,6 +44,20 @@ type Servers = { @@ -44,6 +44,20 @@ type Servers = {
const TEST_SUFFIX = Modes.test ? '_test' : '';
const PREMIUM_SUFFIX = '_premium';
export function getTelegramConnectionSuffix(connectionType: ConnectionType) {
return connectionType === 'client' ? '' : '-1';
}
/// #if MTPROTO_HAS_WS
export function constructTelegramWebSocketUrl(dcId: DcId, connectionType: ConnectionType, premium?: boolean) {
const suffix = getTelegramConnectionSuffix(connectionType);
const path = connectionType !== 'client' ? 'apiws' + (premium ? PREMIUM_SUFFIX : TEST_SUFFIX) : ('apiws' + TEST_SUFFIX);
const chosenServer = `wss://${App.suffix.toLowerCase()}ws${dcId}${suffix}.web.telegram.org/${path}`;
return chosenServer;
}
/// #endif
export class DcConfigurator {
private sslSubdomains = ['pluto', 'venus', 'aurora', 'vesta', 'flora'];
@ -64,9 +78,8 @@ export class DcConfigurator { @@ -64,9 +78,8 @@ export class DcConfigurator {
public chosenServers: Servers = {} as any;
/// #if MTPROTO_HAS_WS
private transportSocket = (dcId: DcId, connectionType: ConnectionType, suffix: string, premium?: boolean) => {
const path = connectionType !== 'client' ? 'apiws' + (premium ? PREMIUM_SUFFIX : TEST_SUFFIX) : ('apiws' + TEST_SUFFIX);
const chosenServer = `wss://${App.suffix.toLowerCase()}ws${dcId}${suffix}.web.telegram.org/${path}`;
private transportSocket = (dcId: DcId, connectionType: ConnectionType, premium?: boolean) => {
const chosenServer = constructTelegramWebSocketUrl(dcId, connectionType, premium);
const logSuffix = connectionType === 'upload' ? '-U' : connectionType === 'download' ? '-D' : '';
const retryTimeout = connectionType === 'client' ? 10000 : 10000;
@ -83,10 +96,11 @@ export class DcConfigurator { @@ -83,10 +96,11 @@ export class DcConfigurator {
/// #endif
/// #if MTPROTO_HAS_HTTP
private transportHTTP = (dcId: DcId, connectionType: ConnectionType, suffix: string, premium?: boolean) => {
private transportHTTP = (dcId: DcId, connectionType: ConnectionType, premium?: boolean) => {
let chosenServer: string;
if(Modes.ssl || !Modes.http) {
const subdomain = this.sslSubdomains[dcId - 1] + (connectionType !== 'client' ? '-1' : '');
const suffix = getTelegramConnectionSuffix(connectionType);
const subdomain = this.sslSubdomains[dcId - 1] + suffix;
const path = Modes.test ? 'apiw_test1' : 'apiw1';
chosenServer = 'https://' + subdomain + '.web.telegram.org/' + path;
} else {
@ -133,14 +147,12 @@ export class DcConfigurator { @@ -133,14 +147,12 @@ export class DcConfigurator {
if(!transports.length || !reuse/* || (upload && transports.length < 1) */) {
let transport: MTTransport;
const suffix = connectionType === 'client' ? '' : '-1';
/// #if MTPROTO_HAS_WS && MTPROTO_HAS_HTTP
transport = (transportType === 'websocket' ? this.transportSocket : this.transportHTTP)(dcId, connectionType, suffix, premium);
transport = (transportType === 'websocket' ? this.transportSocket : this.transportHTTP)(dcId, connectionType, premium);
/// #elif !MTPROTO_HTTP
transport = this.transportSocket(dcId, connectionType, suffix, premium);
transport = this.transportSocket(dcId, connectionType, premium);
/// #else
transport = this.transportHTTP(dcId, connectionType, suffix, premium);
transport = this.transportHTTP(dcId, connectionType, premium);
/// #endif
if(!transport) {

9
src/lib/mtproto/transports/tcpObfuscated.ts

@ -265,6 +265,15 @@ export default class TcpObfuscated implements MTTransport { @@ -265,6 +265,15 @@ export default class TcpObfuscated implements MTTransport {
this.connection.addEventListener('message', this.onMessage);
}
public changeUrl(url: string) {
if(this.url === url) {
return;
}
this.url = url;
this.forceReconnect();
}
private encodeBody(body: Uint8Array) {
const toEncode = this.codec.encodePacket(body);

Loading…
Cancel
Save