Upload files with HTTPS protocol
Forward chat rights
This commit is contained in:
parent
2be9a62a37
commit
94db9c935e
@ -2,7 +2,7 @@ import Scrollable from "./scrollable";
|
|||||||
import appMessagesManager, { Dialog } from "../lib/appManagers/appMessagesManager";
|
import appMessagesManager, { Dialog } from "../lib/appManagers/appMessagesManager";
|
||||||
import { cancelEvent, findUpClassName, findUpAttribute } from "../lib/utils";
|
import { cancelEvent, findUpClassName, findUpAttribute } from "../lib/utils";
|
||||||
import appDialogsManager from "../lib/appManagers/appDialogsManager";
|
import appDialogsManager from "../lib/appManagers/appDialogsManager";
|
||||||
import appChatsManager from "../lib/appManagers/appChatsManager";
|
import appChatsManager, { ChatRights } from "../lib/appManagers/appChatsManager";
|
||||||
import appUsersManager from "../lib/appManagers/appUsersManager";
|
import appUsersManager from "../lib/appManagers/appUsersManager";
|
||||||
import appPeersManager from "../lib/appManagers/appPeersManager";
|
import appPeersManager from "../lib/appManagers/appPeersManager";
|
||||||
import appPhotosManager from "../lib/appManagers/appPhotosManager";
|
import appPhotosManager from "../lib/appManagers/appPhotosManager";
|
||||||
@ -37,7 +37,7 @@ export class AppSelectPeers {
|
|||||||
|
|
||||||
private loadedWhat: Partial<{[k in 'dialogs' | 'archived' | 'contacts']: true}> = {};
|
private loadedWhat: Partial<{[k in 'dialogs' | 'archived' | 'contacts']: true}> = {};
|
||||||
|
|
||||||
constructor(private appendTo: HTMLElement, private onChange?: (length: number) => void, private peerType: PeerType[] = ['dialogs'], onFirstRender?: () => void, private renderResultsFunc?: (peerIDs: number[]) => void) {
|
constructor(private appendTo: HTMLElement, private onChange?: (length: number) => void, private peerType: PeerType[] = ['dialogs'], onFirstRender?: () => void, private renderResultsFunc?: (peerIDs: number[]) => void, private chatRightsAction?: ChatRights) {
|
||||||
this.container.classList.add('selector');
|
this.container.classList.add('selector');
|
||||||
|
|
||||||
if(!this.renderResultsFunc) {
|
if(!this.renderResultsFunc) {
|
||||||
@ -168,6 +168,12 @@ export class AppSelectPeers {
|
|||||||
dialogs = dialogs.slice();
|
dialogs = dialogs.slice();
|
||||||
dialogs.findAndSplice(d => d.peerID == $rootScope.myID); // no my account
|
dialogs.findAndSplice(d => d.peerID == $rootScope.myID); // no my account
|
||||||
|
|
||||||
|
if(this.chatRightsAction) {
|
||||||
|
dialogs = dialogs.filter(d => {
|
||||||
|
return d.peerID > 0 || appChatsManager.hasRights(-d.peerID, this.chatRightsAction);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
this.renderSaved();
|
this.renderSaved();
|
||||||
|
|
||||||
this.offsetIndex = newOffsetIndex;
|
this.offsetIndex = newOffsetIndex;
|
||||||
|
@ -81,6 +81,6 @@ export default class AppForwardTab implements SliderTab {
|
|||||||
appSidebarRight.selectTab(AppSidebarRight.SLIDERITEMSIDS.forward);
|
appSidebarRight.selectTab(AppSidebarRight.SLIDERITEMSIDS.forward);
|
||||||
appSidebarRight.toggleSidebar(true);
|
appSidebarRight.toggleSidebar(true);
|
||||||
document.body.classList.add('is-forward-active');
|
document.body.classList.add('is-forward-active');
|
||||||
});
|
}, null, 'send');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -29,7 +29,7 @@ export class ApiUpdatesManager {
|
|||||||
public channelStates: any = {};
|
public channelStates: any = {};
|
||||||
private attached = false;
|
private attached = false;
|
||||||
|
|
||||||
private log = logger('UPDATES'/* , LogLevels.error */);
|
private log = logger('UPDATES', LogLevels.error);
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
appStateManager.addListener('save', () => {
|
appStateManager.addListener('save', () => {
|
||||||
|
@ -59,6 +59,8 @@ export type Chat = {
|
|||||||
default_banned_rights?: any
|
default_banned_rights?: any
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export type ChatRights = 'send' | 'edit_title' | 'edit_photo' | 'invite' | 'pin' | 'deleteRevoke';
|
||||||
|
|
||||||
export class AppChatsManager {
|
export class AppChatsManager {
|
||||||
public chats: {[id: number]: Channel | Chat | any} = {};
|
public chats: {[id: number]: Channel | Chat | any} = {};
|
||||||
public usernames: any = {};
|
public usernames: any = {};
|
||||||
@ -149,7 +151,7 @@ export class AppChatsManager {
|
|||||||
return this.chats[id] || {_: 'chatEmpty', id: id, deleted: true, access_hash: this.channelAccess[id]};
|
return this.chats[id] || {_: 'chatEmpty', id: id, deleted: true, access_hash: this.channelAccess[id]};
|
||||||
}
|
}
|
||||||
|
|
||||||
public hasRights(id: number, action: 'send' | 'edit_title' | 'edit_photo' | 'invite' | 'pin' | 'deleteRevoke') {
|
public hasRights(id: number, action: ChatRights) {
|
||||||
const chat = this.getChat(id);
|
const chat = this.getChat(id);
|
||||||
if(chat._ == 'chatEmpty') return false;
|
if(chat._ == 'chatEmpty') return false;
|
||||||
|
|
||||||
|
@ -1,21 +1,17 @@
|
|||||||
import AppStorage from '../storage';
|
import AppStorage from '../storage';
|
||||||
|
|
||||||
import { MTPNetworker } from './networker';
|
import MTPNetworker from './networker';
|
||||||
import { bytesFromHex, bytesToHex, isObject } from '../bin_utils';
|
import { bytesFromHex, bytesToHex, isObject } from '../bin_utils';
|
||||||
import networkerFactory from './networkerFactory';
|
import networkerFactory from './networkerFactory';
|
||||||
//import { telegramMeWebService } from './mtproto';
|
//import { telegramMeWebService } from './mtproto';
|
||||||
import authorizer from './authorizer';
|
import authorizer from './authorizer';
|
||||||
import {App, Modes, MOUNT_CLASS_TO} from './mtproto_config';
|
import {App, Modes, MOUNT_CLASS_TO} from './mtproto_config';
|
||||||
import dcConfigurator from './dcConfigurator';
|
import dcConfigurator, { ConnectionType, TransportType } from './dcConfigurator';
|
||||||
import { logger } from '../logger';
|
import { logger } from '../logger';
|
||||||
import type { InvokeApiOptions } from '../../types';
|
import type { InvokeApiOptions } from '../../types';
|
||||||
import type { MethodDeclMap } from '../../layer';
|
import type { MethodDeclMap } from '../../layer';
|
||||||
import { CancellablePromise, deferredPromise } from '../../helpers/cancellablePromise';
|
import { CancellablePromise, deferredPromise } from '../../helpers/cancellablePromise';
|
||||||
|
|
||||||
/// #if MTPROTO_HTTP
|
|
||||||
import HTTP from './transports/http';
|
|
||||||
/// #endif
|
|
||||||
|
|
||||||
/// #if !MTPROTO_WORKER
|
/// #if !MTPROTO_WORKER
|
||||||
import $rootScope from '../rootScope';
|
import $rootScope from '../rootScope';
|
||||||
/// #endif
|
/// #endif
|
||||||
@ -35,8 +31,14 @@ export type ApiError = Partial<{
|
|||||||
}>;
|
}>;
|
||||||
|
|
||||||
export class ApiManager {
|
export class ApiManager {
|
||||||
public cachedNetworkers: {[x: number]: MTPNetworker} = {};
|
public cachedNetworkers: {
|
||||||
public cachedUploadNetworkers: {[x: number]: MTPNetworker} = {};
|
[transportType in TransportType]: {
|
||||||
|
[connectionType in ConnectionType]: {
|
||||||
|
[dcID: number]: MTPNetworker
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} = {} as any;
|
||||||
|
|
||||||
public cachedExportPromise: {[x: number]: Promise<unknown>} = {};
|
public cachedExportPromise: {[x: number]: Promise<unknown>} = {};
|
||||||
private gettingNetworkers: {[dcIDAndType: string]: Promise<MTPNetworker>} = {};
|
private gettingNetworkers: {[dcIDAndType: string]: Promise<MTPNetworker>} = {};
|
||||||
public baseDcID = 0;
|
public baseDcID = 0;
|
||||||
@ -115,27 +117,30 @@ export class ApiManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// mtpGetNetworker
|
// mtpGetNetworker
|
||||||
public async getNetworker(dcID: number, options: InvokeApiOptions = {}): Promise<MTPNetworker> {
|
public getNetworker(dcID: number, options: InvokeApiOptions = {}): Promise<MTPNetworker> {
|
||||||
/// #if MTPROTO_HTTP
|
|
||||||
// @ts-ignore
|
|
||||||
const upload = (options.fileUpload || options.fileDownload);
|
|
||||||
/// #else
|
|
||||||
// @ts-ignore
|
|
||||||
const upload = (options.fileUpload || options.fileDownload) && Modes.multipleConnections;
|
|
||||||
/// #endif
|
|
||||||
|
|
||||||
const transport = dcConfigurator.chooseServer(dcID, upload);
|
|
||||||
const cache = upload ? this.cachedUploadNetworkers : this.cachedNetworkers;
|
|
||||||
|
|
||||||
if(!dcID) {
|
if(!dcID) {
|
||||||
throw new Error('get Networker without dcID');
|
throw new Error('get Networker without dcID');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const connectionType: ConnectionType = options.fileDownload ? 'download' : (options.fileUpload ? 'upload' : 'client');
|
||||||
|
const transportType: TransportType = connectionType == 'upload' ? 'https' : 'websocket';
|
||||||
|
const transport = dcConfigurator.chooseServer(dcID, connectionType, transportType);
|
||||||
|
|
||||||
|
if(!this.cachedNetworkers.hasOwnProperty(transportType)) {
|
||||||
|
this.cachedNetworkers[transportType] = {
|
||||||
|
client: {},
|
||||||
|
download: {},
|
||||||
|
upload: {}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
const cache = this.cachedNetworkers[transportType][connectionType];
|
||||||
|
|
||||||
if(cache[dcID] !== undefined) {
|
if(cache[dcID] !== undefined) {
|
||||||
return cache[dcID];
|
return Promise.resolve(cache[dcID]);
|
||||||
}
|
}
|
||||||
|
|
||||||
const getKey = dcID + '-' + +upload;
|
const getKey = [dcID, transportType, connectionType].join('-');
|
||||||
if(this.gettingNetworkers[getKey]) {
|
if(this.gettingNetworkers[getKey]) {
|
||||||
return this.gettingNetworkers[getKey];
|
return this.gettingNetworkers[getKey];
|
||||||
}
|
}
|
||||||
@ -146,12 +151,6 @@ export class ApiManager {
|
|||||||
|
|
||||||
return this.gettingNetworkers[getKey] = AppStorage.get<string[]/* |boolean[] */>([ak, akID, ss])
|
return this.gettingNetworkers[getKey] = AppStorage.get<string[]/* |boolean[] */>([ak, akID, ss])
|
||||||
.then(async([authKeyHex, authKeyIDHex, serverSaltHex]) => {
|
.then(async([authKeyHex, authKeyIDHex, serverSaltHex]) => {
|
||||||
/* if(authKeyHex && !authKeyIDHex && serverSaltHex) {
|
|
||||||
this.log.warn('Updating to new version (+akID)');
|
|
||||||
await AppStorage.remove(ak, akID, ss);
|
|
||||||
authKeyHex = serverSaltHex = '';
|
|
||||||
} */
|
|
||||||
|
|
||||||
let networker: MTPNetworker;
|
let networker: MTPNetworker;
|
||||||
if(authKeyHex && authKeyHex.length == 512) {
|
if(authKeyHex && authKeyHex.length == 512) {
|
||||||
if(!serverSaltHex || serverSaltHex.length != 16) {
|
if(!serverSaltHex || serverSaltHex.length != 16) {
|
||||||
@ -162,7 +161,7 @@ export class ApiManager {
|
|||||||
const authKeyID = new Uint8Array(bytesFromHex(authKeyIDHex));
|
const authKeyID = new Uint8Array(bytesFromHex(authKeyIDHex));
|
||||||
const serverSalt = bytesFromHex(serverSaltHex);
|
const serverSalt = bytesFromHex(serverSaltHex);
|
||||||
|
|
||||||
networker = networkerFactory.getNetworker(dcID, authKey, authKeyID, serverSalt, options);
|
networker = networkerFactory.getNetworker(dcID, authKey, authKeyID, serverSalt, transport, options);
|
||||||
} else {
|
} else {
|
||||||
try { // if no saved state
|
try { // if no saved state
|
||||||
const auth = await authorizer.auth(dcID);
|
const auth = await authorizer.auth(dcID);
|
||||||
@ -175,7 +174,7 @@ export class ApiManager {
|
|||||||
|
|
||||||
AppStorage.set(storeObj);
|
AppStorage.set(storeObj);
|
||||||
|
|
||||||
networker = networkerFactory.getNetworker(dcID, auth.authKey, auth.authKeyID, auth.serverSalt, options);
|
networker = networkerFactory.getNetworker(dcID, auth.authKey, auth.authKeyID, auth.serverSalt, transport, options);
|
||||||
} catch(error) {
|
} catch(error) {
|
||||||
this.log('Get networker error', error, error.stack);
|
this.log('Get networker error', error, error.stack);
|
||||||
delete this.gettingNetworkers[getKey];
|
delete this.gettingNetworkers[getKey];
|
||||||
|
@ -1,13 +1,27 @@
|
|||||||
import MTTransport from './transports/transport';
|
import MTTransport from './transports/transport';
|
||||||
import { Modes } from './mtproto_config';
|
import { Modes } from './mtproto_config';
|
||||||
|
|
||||||
/// #if !MTPROTO_HTTP
|
/// #if MTPROTO_HTTP_UPLOAD
|
||||||
|
// @ts-ignore
|
||||||
|
import Socket from './transports/websocket';
|
||||||
|
// @ts-ignore
|
||||||
|
import HTTP from './transports/http';
|
||||||
|
/// #elif !MTPROTO_HTTP
|
||||||
|
// @ts-ignore
|
||||||
import Socket from './transports/websocket';
|
import Socket from './transports/websocket';
|
||||||
/// #else
|
/// #else
|
||||||
|
// @ts-ignore
|
||||||
import HTTP from './transports/http';
|
import HTTP from './transports/http';
|
||||||
/// #endif
|
/// #endif
|
||||||
|
|
||||||
|
export type TransportType = 'websocket' | 'https' | 'http';
|
||||||
|
export type ConnectionType = 'client' | 'download' | 'upload';
|
||||||
type Servers = {
|
type Servers = {
|
||||||
[dcID: number]: MTTransport[]
|
[transportType in TransportType]: {
|
||||||
|
[connectionType in ConnectionType]: {
|
||||||
|
[dcID: number]: MTTransport[]
|
||||||
|
}
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
export class DcConfigurator {
|
export class DcConfigurator {
|
||||||
@ -27,13 +41,45 @@ export class DcConfigurator {
|
|||||||
{id: 5, host: '149.154.171.5', port: 80}
|
{id: 5, host: '149.154.171.5', port: 80}
|
||||||
];
|
];
|
||||||
|
|
||||||
private chosenServers: Servers = {};
|
private chosenServers: Servers = {} as any;
|
||||||
private chosenUploadServers: Servers = {};
|
|
||||||
|
|
||||||
public chooseServer(dcID: number, upload?: boolean) {
|
private transportSocket = (dcID: number, connectionType: ConnectionType) => {
|
||||||
const servers = upload && Modes.multipleConnections
|
const subdomain = this.sslSubdomains[dcID - 1];
|
||||||
? this.chosenUploadServers
|
const path = Modes.test ? 'apiws_test' : 'apiws';
|
||||||
: this.chosenServers;
|
const chosenServer = 'wss://' + subdomain + '.web.telegram.org/' + path;
|
||||||
|
return new Socket(dcID, chosenServer, connectionType != 'client' ? '-U' : '');
|
||||||
|
};
|
||||||
|
|
||||||
|
private transportHTTP = (dcID: number, connectionType: ConnectionType) => {
|
||||||
|
if(Modes.ssl || !Modes.http) {
|
||||||
|
const subdomain = this.sslSubdomains[dcID - 1] + (connectionType != 'client' ? '-1' : '');
|
||||||
|
const path = Modes.test ? 'apiw_test1' : 'apiw1';
|
||||||
|
const chosenServer = 'https://' + subdomain + '.web.telegram.org/' + path;
|
||||||
|
return new HTTP(dcID, chosenServer);
|
||||||
|
} else {
|
||||||
|
for(let dcOption of this.dcOptions) {
|
||||||
|
if(dcOption.id == dcID) {
|
||||||
|
const chosenServer = 'http://' + dcOption.host + (dcOption.port != 80 ? ':' + dcOption.port : '') + '/apiw1';
|
||||||
|
return new HTTP(dcID, chosenServer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
public chooseServer(dcID: number, connectionType: ConnectionType = 'client', transportType: TransportType = 'websocket') {
|
||||||
|
/* if(transportType == 'websocket' && !Modes.multipleConnections) {
|
||||||
|
connectionType = 'client';
|
||||||
|
} */
|
||||||
|
|
||||||
|
if(!this.chosenServers.hasOwnProperty(transportType)) {
|
||||||
|
this.chosenServers[transportType] = {
|
||||||
|
client: {},
|
||||||
|
download: {},
|
||||||
|
upload: {}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
const servers = this.chosenServers[transportType][connectionType];
|
||||||
|
|
||||||
if(!(dcID in servers)) {
|
if(!(dcID in servers)) {
|
||||||
servers[dcID] = [];
|
servers[dcID] = [];
|
||||||
@ -41,32 +87,15 @@ export class DcConfigurator {
|
|||||||
|
|
||||||
const transports = servers[dcID];
|
const transports = servers[dcID];
|
||||||
|
|
||||||
if(!transports.length || (upload && transports.length < 1)) {
|
if(!transports.length/* || (upload && transports.length < 1) */) {
|
||||||
let transport: MTTransport;
|
let transport: MTTransport;
|
||||||
|
|
||||||
/// #if !MTPROTO_HTTP
|
/// #if MTPROTO_HTTP_UPLOAD
|
||||||
//if(transportType == 'websocket') {
|
transport = (transportType == 'websocket' ? this.transportSocket : this.transportHTTP)(dcID, connectionType);
|
||||||
const subdomain = this.sslSubdomains[dcID - 1];
|
/// #elif !MTPROTO_HTTP
|
||||||
const path = Modes.test ? 'apiws_test' : 'apiws';
|
transport = this.transportSocket(dcID, connectionType);
|
||||||
const chosenServer = 'wss://' + subdomain + '.web.telegram.org/' + path;
|
|
||||||
transport = new Socket(dcID, chosenServer, upload ? '-U' : '');
|
|
||||||
//} else
|
|
||||||
/// #else
|
/// #else
|
||||||
// @ts-ignore
|
transport = this.transportHTTP(dcID, connectionType);
|
||||||
if(Modes.ssl || !Modes.http) {
|
|
||||||
const subdomain = this.sslSubdomains[dcID - 1] + (upload ? '-1' : '');
|
|
||||||
const path = Modes.test ? 'apiw_test1' : 'apiw1';
|
|
||||||
const chosenServer = 'https://' + subdomain + '.web.telegram.org/' + path;
|
|
||||||
transport = new HTTP(dcID, chosenServer);
|
|
||||||
} else {
|
|
||||||
for(let dcOption of this.dcOptions) {
|
|
||||||
if(dcOption.id == dcID) {
|
|
||||||
const chosenServer = 'http://' + dcOption.host + (dcOption.port != 80 ? ':' + dcOption.port : '') + '/apiw1';
|
|
||||||
transport = new HTTP(dcID, chosenServer);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/// #endif
|
/// #endif
|
||||||
|
|
||||||
if(!transport) {
|
if(!transport) {
|
||||||
|
@ -9,17 +9,23 @@ import Schema from './schema';
|
|||||||
|
|
||||||
import timeManager from './timeManager';
|
import timeManager from './timeManager';
|
||||||
import NetworkerFactory from './networkerFactory';
|
import NetworkerFactory from './networkerFactory';
|
||||||
import dcConfigurator from './dcConfigurator';
|
|
||||||
import { logger, LogLevels } from '../logger';
|
import { logger, LogLevels } from '../logger';
|
||||||
import { Modes, App } from './mtproto_config';
|
import { Modes, App } from './mtproto_config';
|
||||||
import { InvokeApiOptions } from '../../types';
|
import { InvokeApiOptions } from '../../types';
|
||||||
import { longToBytes } from '../crypto/crypto_utils';
|
import { longToBytes } from '../crypto/crypto_utils';
|
||||||
import MTTransport from './transports/transport';
|
import MTTransport from './transports/transport';
|
||||||
|
|
||||||
/// #if MTPROTO_HTTP
|
/// #if MTPROTO_HTTP_UPLOAD
|
||||||
import type HTTP from './transports/http';
|
// @ts-ignore
|
||||||
|
import HTTP from './transports/http';
|
||||||
|
// @ts-ignore
|
||||||
|
import Socket from './transports/websocket';
|
||||||
|
/// #elif MTPROTO_HTTP
|
||||||
|
// @ts-ignore
|
||||||
|
import HTTP from './transports/http';
|
||||||
/// #else
|
/// #else
|
||||||
import type Socket from './transports/websocket';
|
// @ts-ignore
|
||||||
|
import Socket from './transports/websocket';
|
||||||
/// #endif
|
/// #endif
|
||||||
|
|
||||||
//console.error('networker included!', new Error().stack);
|
//console.error('networker included!', new Error().stack);
|
||||||
@ -62,7 +68,7 @@ type Message = InvokeApiOptions & MessageOptions & {
|
|||||||
noResponse?: true, // only with http (http_wait for longPoll)
|
noResponse?: true, // only with http (http_wait for longPoll)
|
||||||
};
|
};
|
||||||
|
|
||||||
class MTPNetworker {
|
export default class MTPNetworker {
|
||||||
private authKeyUint8: Uint8Array;
|
private authKeyUint8: Uint8Array;
|
||||||
|
|
||||||
private upload: boolean;
|
private upload: boolean;
|
||||||
@ -73,19 +79,18 @@ class MTPNetworker {
|
|||||||
[msgID: string]: Message
|
[msgID: string]: Message
|
||||||
} = {};
|
} = {};
|
||||||
|
|
||||||
private pendingMessages: any = {};
|
private pendingMessages: {[msgID: string]: number} = {};
|
||||||
private pendingAcks: Array<string> = [];
|
private pendingAcks: Array<string> = [];
|
||||||
private pendingResends: Array<string> = [];
|
private pendingResends: Array<string> = [];
|
||||||
private connectionInited = false;
|
private connectionInited = false;
|
||||||
|
|
||||||
/// #if MTPROTO_HTTP
|
/// #if MTPROTO_HTTP || MTPROTO_HTTP_UPLOAD
|
||||||
//private longPollInt: number;
|
//private longPollInt: number;
|
||||||
private longPollPending = 0;
|
private longPollPending = 0;
|
||||||
private nextReqTimeout: number;
|
private nextReqTimeout: number;
|
||||||
private nextReq: number = 0;
|
private nextReq: number = 0;
|
||||||
private checkConnectionTimeout: number;
|
private checkConnectionTimeout: number;
|
||||||
private checkConnectionPeriod = 0;
|
private checkConnectionPeriod = 0;
|
||||||
private onOnlineCb = this.checkConnection.bind(this);
|
|
||||||
private sleepAfter = 0;
|
private sleepAfter = 0;
|
||||||
private offline = false;
|
private offline = false;
|
||||||
/// #endif
|
/// #endif
|
||||||
@ -99,19 +104,20 @@ class MTPNetworker {
|
|||||||
resend_msg_ids: Array<string>
|
resend_msg_ids: Array<string>
|
||||||
} | null = null;
|
} | null = null;
|
||||||
|
|
||||||
private transport: MTTransport;
|
//private transport: MTTransport;
|
||||||
|
|
||||||
private log: ReturnType<typeof logger>;
|
private log: ReturnType<typeof logger>;
|
||||||
|
|
||||||
constructor(private dcID: number, private authKey: number[], private authKeyID: Uint8Array,
|
constructor(private dcID: number, private authKey: number[], private authKeyID: Uint8Array,
|
||||||
private serverSalt: number[], private options: InvokeApiOptions = {}) {
|
private serverSalt: number[], private transport: MTTransport, private options: InvokeApiOptions = {}) {
|
||||||
this.authKeyUint8 = convertToUint8Array(this.authKey);
|
this.authKeyUint8 = convertToUint8Array(this.authKey);
|
||||||
//this.authKeyID = sha1BytesSync(this.authKey).slice(-8);
|
//this.authKeyID = sha1BytesSync(this.authKey).slice(-8);
|
||||||
|
|
||||||
//console.trace('Create', dcID, options);
|
//console.trace('Create', dcID, options);
|
||||||
|
|
||||||
this.upload = this.options.fileUpload || this.options.fileDownload;
|
this.upload = this.options.fileUpload || this.options.fileDownload;
|
||||||
this.log = logger('NET-' + dcID + (this.upload ? '-U' : ''), this.upload && this.dcID == 2 ? LogLevels.debug | LogLevels.warn | LogLevels.log | LogLevels.error : LogLevels.error);
|
//this.log = logger('NET-' + dcID + (this.upload ? '-U' : ''), this.upload && this.dcID == 2 ? LogLevels.debug | LogLevels.warn | LogLevels.log | LogLevels.error : LogLevels.error);
|
||||||
|
this.log = logger('NET-' + dcID + (this.upload ? '-U' : ''), LogLevels.log | LogLevels.error);
|
||||||
this.log('constructor'/* , this.authKey, this.authKeyID, this.serverSalt */);
|
this.log('constructor'/* , this.authKey, this.authKeyID, this.serverSalt */);
|
||||||
|
|
||||||
/* // Test resend after bad_server_salt
|
/* // Test resend after bad_server_salt
|
||||||
@ -127,9 +133,14 @@ class MTPNetworker {
|
|||||||
// $rootScope.offlineConnecting = true */
|
// $rootScope.offlineConnecting = true */
|
||||||
// }
|
// }
|
||||||
|
|
||||||
this.transport = dcConfigurator.chooseServer(this.dcID, this.upload);
|
/// #if MTPROTO_HTTP_UPLOAD
|
||||||
|
if(this.transport instanceof HTTP) {
|
||||||
/// #if MTPROTO_HTTP
|
/* this.longPollInt = */setInterval(this.checkLongPoll.bind(this), 10000);
|
||||||
|
this.checkLongPoll();
|
||||||
|
} else {
|
||||||
|
(this.transport as Socket).networker = this;
|
||||||
|
}
|
||||||
|
/// #elif MTPROTO_HTTP
|
||||||
//if(this.transport instanceof HTTP) {
|
//if(this.transport instanceof HTTP) {
|
||||||
/* this.longPollInt = */setInterval(this.checkLongPoll.bind(this), 10000);
|
/* this.longPollInt = */setInterval(this.checkLongPoll.bind(this), 10000);
|
||||||
this.checkLongPoll();
|
this.checkLongPoll();
|
||||||
@ -294,10 +305,10 @@ class MTPNetworker {
|
|||||||
return this.pushMessage(message, options);
|
return this.pushMessage(message, options);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// #if MTPROTO_HTTP
|
/// #if MTPROTO_HTTP || MTPROTO_HTTP_UPLOAD
|
||||||
public checkLongPoll() {
|
public checkLongPoll() {
|
||||||
const isClean = this.cleanupSent();
|
const isClean = this.cleanupSent();
|
||||||
//this.log('Check lp', this.longPollPending, tsNow(), this.dcID, isClean, this);
|
//this.log.error('Check lp', this.longPollPending, this.dcID, isClean, this);
|
||||||
if((this.longPollPending && Date.now() < this.longPollPending) ||
|
if((this.longPollPending && Date.now() < this.longPollPending) ||
|
||||||
this.offline) {
|
this.offline) {
|
||||||
//this.log('No lp this time');
|
//this.log('No lp this time');
|
||||||
@ -339,7 +350,7 @@ class MTPNetworker {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public checkConnection(event: Event | string) {
|
public checkConnection = (event: Event | string) => {
|
||||||
/* $rootScope.offlineConnecting = true */
|
/* $rootScope.offlineConnecting = true */
|
||||||
|
|
||||||
this.log('Check connection', event);
|
this.log('Check connection', event);
|
||||||
@ -373,7 +384,7 @@ class MTPNetworker {
|
|||||||
delete $rootScope.offlineConnecting
|
delete $rootScope.offlineConnecting
|
||||||
}, 1000); */
|
}, 1000); */
|
||||||
});
|
});
|
||||||
}
|
};
|
||||||
|
|
||||||
public toggleOffline(enabled: boolean) {
|
public toggleOffline(enabled: boolean) {
|
||||||
// this.log('toggle ', enabled, this.dcID, this.iii)
|
// this.log('toggle ', enabled, this.dcID, this.iii)
|
||||||
@ -397,21 +408,71 @@ class MTPNetworker {
|
|||||||
this.checkConnectionTimeout = setTimeout(this.checkConnection.bind(this), this.checkConnectionPeriod * 1000 | 0);
|
this.checkConnectionTimeout = setTimeout(this.checkConnection.bind(this), this.checkConnectionPeriod * 1000 | 0);
|
||||||
this.checkConnectionPeriod = Math.min(30, (1 + this.checkConnectionPeriod) * 1.5);
|
this.checkConnectionPeriod = Math.min(30, (1 + this.checkConnectionPeriod) * 1.5);
|
||||||
|
|
||||||
document.body.addEventListener('online', this.onOnlineCb, false);
|
document.body.addEventListener('online', this.checkConnection, false);
|
||||||
document.body.addEventListener('focus', this.onOnlineCb, false);
|
document.body.addEventListener('focus', this.checkConnection, false);
|
||||||
} else {
|
} else {
|
||||||
this.checkLongPoll();
|
this.checkLongPoll();
|
||||||
|
|
||||||
this.scheduleRequest();
|
this.scheduleRequest();
|
||||||
|
|
||||||
document.body.removeEventListener('online', this.onOnlineCb);
|
document.body.removeEventListener('online', this.checkConnection);
|
||||||
document.body.removeEventListener('focus', this.onOnlineCb);
|
document.body.removeEventListener('focus', this.checkConnection);
|
||||||
|
|
||||||
clearTimeout(this.checkConnectionTimeout);
|
clearTimeout(this.checkConnectionTimeout);
|
||||||
this.checkConnectionTimeout = 0;
|
this.checkConnectionTimeout = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private handleSentEncryptedRequestHTTP(promise: ReturnType<MTPNetworker['sendEncryptedRequest']>, message: Message, noResponseMsgs: string[]) {
|
||||||
|
promise
|
||||||
|
.then((result) => {
|
||||||
|
this.toggleOffline(false);
|
||||||
|
// this.log('parse for', message)
|
||||||
|
this.parseResponse(result).then((response) => {
|
||||||
|
if(Modes.debug) {
|
||||||
|
this.log('Server response', this.dcID, response);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.processMessage(response.response, response.messageID, response.sessionID);
|
||||||
|
|
||||||
|
noResponseMsgs.forEach((msgID) => {
|
||||||
|
if(this.sentMessages[msgID]) {
|
||||||
|
var deferred = this.sentMessages[msgID].deferred;
|
||||||
|
delete this.sentMessages[msgID];
|
||||||
|
deferred.resolve();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
this.checkLongPoll();
|
||||||
|
|
||||||
|
this.checkConnectionPeriod = Math.max(1.1, Math.sqrt(this.checkConnectionPeriod));
|
||||||
|
});
|
||||||
|
}, (error) => {
|
||||||
|
this.log.error('Encrypted request failed', error, message);
|
||||||
|
|
||||||
|
if(message.container) {
|
||||||
|
message.inner.forEach((msgID: string) => {
|
||||||
|
this.pendingMessages[msgID] = 0;
|
||||||
|
});
|
||||||
|
|
||||||
|
delete this.sentMessages[message.msg_id];
|
||||||
|
} else {
|
||||||
|
this.pendingMessages[message.msg_id] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
noResponseMsgs.forEach((msgID) => {
|
||||||
|
if(this.sentMessages[msgID]) {
|
||||||
|
var deferred = this.sentMessages[msgID].deferred;
|
||||||
|
delete this.sentMessages[msgID];
|
||||||
|
delete this.pendingMessages[msgID];
|
||||||
|
deferred.reject();
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
this.toggleOffline(true);
|
||||||
|
});
|
||||||
|
}
|
||||||
/// #endif
|
/// #endif
|
||||||
|
|
||||||
// тут можно сделать таймаут и выводить дисконнект
|
// тут можно сделать таймаут и выводить дисконнект
|
||||||
@ -502,7 +563,7 @@ class MTPNetworker {
|
|||||||
public performScheduledRequest() {
|
public performScheduledRequest() {
|
||||||
// this.log('scheduled', this.dcID, this.iii)
|
// this.log('scheduled', this.dcID, this.iii)
|
||||||
|
|
||||||
/// #if MTPROTO_HTTP
|
/// #if MTPROTO_HTTP || MTPROTO_HTTP_UPLOAD
|
||||||
if(this.offline) {
|
if(this.offline) {
|
||||||
this.log('Cancel scheduled');
|
this.log('Cancel scheduled');
|
||||||
return false;
|
return false;
|
||||||
@ -597,8 +658,11 @@ class MTPNetworker {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// #if MTPROTO_HTTP
|
/// #if MTPROTO_HTTP_UPLOAD
|
||||||
if(hasApiCall && !hasHttpWait/* && this.transport instanceof HTTP */) {
|
if(this.transport instanceof HTTP)
|
||||||
|
/// #endif
|
||||||
|
/// #if MTPROTO_HTTP || MTPROTO_HTTP_UPLOAD
|
||||||
|
if(hasApiCall && !hasHttpWait) {
|
||||||
var serializer = new TLSerialization({mtproto: true});
|
var serializer = new TLSerialization({mtproto: true});
|
||||||
serializer.storeMethod('http_wait', {
|
serializer.storeMethod('http_wait', {
|
||||||
max_delay: 500,
|
max_delay: 500,
|
||||||
@ -670,57 +734,18 @@ class MTPNetworker {
|
|||||||
|
|
||||||
let promise = this.sendEncryptedRequest(message);
|
let promise = this.sendEncryptedRequest(message);
|
||||||
|
|
||||||
/// #if !MTPROTO_HTTP
|
/// #if MTPROTO_HTTP_UPLOAD
|
||||||
|
if(!(this.transport instanceof HTTP)) {
|
||||||
|
if(noResponseMsgs.length) this.log.error('noResponseMsgs length!', noResponseMsgs);
|
||||||
|
} else {
|
||||||
|
this.handleSentEncryptedRequestHTTP(promise, message, noResponseMsgs);
|
||||||
|
}
|
||||||
|
/// #elif !MTPROTO_HTTP
|
||||||
//if(!(this.transport instanceof HTTP)) {
|
//if(!(this.transport instanceof HTTP)) {
|
||||||
if(noResponseMsgs.length) this.log.error('noResponseMsgs length!', noResponseMsgs);
|
if(noResponseMsgs.length) this.log.error('noResponseMsgs length!', noResponseMsgs);
|
||||||
//} else {
|
//} else {
|
||||||
/// #else
|
/// #else
|
||||||
promise.then((result) => {
|
this.handleSentEncryptedRequestHTTP(promise, message, noResponseMsgs);
|
||||||
self.toggleOffline(false);
|
|
||||||
// this.log('parse for', message)
|
|
||||||
self.parseResponse(result).then((response) => {
|
|
||||||
if(Modes.debug) {
|
|
||||||
this.log('Server response', self.dcID, response);
|
|
||||||
}
|
|
||||||
|
|
||||||
self.processMessage(response.response, response.messageID, response.sessionID);
|
|
||||||
|
|
||||||
noResponseMsgs.forEach((msgID) => {
|
|
||||||
if(self.sentMessages[msgID]) {
|
|
||||||
var deferred = self.sentMessages[msgID].deferred;
|
|
||||||
delete self.sentMessages[msgID];
|
|
||||||
deferred.resolve();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
self.checkLongPoll();
|
|
||||||
|
|
||||||
this.checkConnectionPeriod = Math.max(1.1, Math.sqrt(this.checkConnectionPeriod));
|
|
||||||
});
|
|
||||||
}, (error) => {
|
|
||||||
this.log.error('Encrypted request failed', error, message);
|
|
||||||
|
|
||||||
if(message.container) {
|
|
||||||
message.inner.forEach((msgID: string) => {
|
|
||||||
self.pendingMessages[msgID] = 0;
|
|
||||||
});
|
|
||||||
|
|
||||||
delete self.sentMessages[message.msg_id];
|
|
||||||
} else {
|
|
||||||
self.pendingMessages[message.msg_id] = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
noResponseMsgs.forEach((msgID) => {
|
|
||||||
if(self.sentMessages[msgID]) {
|
|
||||||
var deferred = self.sentMessages[msgID].deferred;
|
|
||||||
delete self.sentMessages[msgID];
|
|
||||||
delete self.pendingMessages[msgID];
|
|
||||||
deferred.reject();
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
self.toggleOffline(true);
|
|
||||||
});
|
|
||||||
//}
|
//}
|
||||||
/// #endif
|
/// #endif
|
||||||
|
|
||||||
@ -807,9 +832,10 @@ class MTPNetworker {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const promise = this.transport.send(requestData);
|
const promise = this.transport.send(requestData);
|
||||||
/// #if !MTPROTO_HTTP
|
/// #if !MTPROTO_HTTP && !MTPROTO_HTTP_UPLOAD
|
||||||
/* if(!(this.transport instanceof HTTP)) */ return promise;
|
/* if(!(this.transport instanceof HTTP)) */ return promise;
|
||||||
/// #else
|
/// #else
|
||||||
|
if(!(this.transport instanceof HTTP)) return promise;
|
||||||
|
|
||||||
return promise.then((result) => {
|
return promise.then((result) => {
|
||||||
if(!result || !result.byteLength) {
|
if(!result || !result.byteLength) {
|
||||||
@ -955,12 +981,13 @@ class MTPNetworker {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public scheduleRequest(delay = 0) {
|
public scheduleRequest(delay = 0) {
|
||||||
/// #if !MTPROTO_HTTP
|
/// #if !MTPROTO_HTTP && !MTPROTO_HTTP_UPLOAD
|
||||||
/* clearTimeout(this.nextReqTimeout);
|
/* clearTimeout(this.nextReqTimeout);
|
||||||
this.nextReqTimeout = self.setTimeout(this.performScheduledRequest.bind(this), delay || 0);
|
this.nextReqTimeout = self.setTimeout(this.performScheduledRequest.bind(this), delay || 0);
|
||||||
return; */
|
return; */
|
||||||
return this.performScheduledRequest();
|
return this.performScheduledRequest();
|
||||||
/// #else
|
/// #else
|
||||||
|
if(!(this.transport instanceof HTTP)) return this.performScheduledRequest();
|
||||||
if(this.offline/* && this.transport instanceof HTTP */) {
|
if(this.offline/* && this.transport instanceof HTTP */) {
|
||||||
this.checkConnection('forced schedule');
|
this.checkConnection('forced schedule');
|
||||||
}
|
}
|
||||||
@ -1127,7 +1154,7 @@ class MTPNetworker {
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case 'bad_msg_notification':
|
case 'bad_msg_notification':
|
||||||
this.log('Bad msg notification', message);
|
this.log.error('Bad msg notification', message);
|
||||||
var sentMessage = this.sentMessages[message.bad_msg_id];
|
var sentMessage = this.sentMessages[message.bad_msg_id];
|
||||||
if(!sentMessage || sentMessage.seq_no != message.bad_msg_seqno) {
|
if(!sentMessage || sentMessage.seq_no != message.bad_msg_seqno) {
|
||||||
this.log(message.bad_msg_id, message.bad_msg_seqno);
|
this.log(message.bad_msg_id, message.bad_msg_seqno);
|
||||||
@ -1268,5 +1295,3 @@ class MTPNetworker {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export {MTPNetworker};
|
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
import { MTPNetworker } from "./networker";
|
import MTPNetworker from "./networker";
|
||||||
import { InvokeApiOptions } from "../../types";
|
import { InvokeApiOptions } from "../../types";
|
||||||
|
import MTTransport from "./transports/transport";
|
||||||
|
|
||||||
export class NetworkerFactory {
|
export class NetworkerFactory {
|
||||||
public updatesProcessor: (obj: any, bool: boolean) => void = null;
|
public updatesProcessor: (obj: any, bool: boolean) => void = null;
|
||||||
@ -8,9 +9,9 @@ export class NetworkerFactory {
|
|||||||
this.updatesProcessor = callback;
|
this.updatesProcessor = callback;
|
||||||
}
|
}
|
||||||
|
|
||||||
public getNetworker(dcID: number, authKey: number[], authKeyID: Uint8Array, serverSalt: number[], options: InvokeApiOptions) {
|
public getNetworker(dcID: number, authKey: number[], authKeyID: Uint8Array, serverSalt: number[], transport: MTTransport, options: InvokeApiOptions) {
|
||||||
//console.log('NetworkerFactory: creating new instance of MTPNetworker:', dcID, options);
|
//console.log('NetworkerFactory: creating new instance of MTPNetworker:', dcID, options);
|
||||||
return new MTPNetworker(dcID, authKey, authKeyID, serverSalt, options);
|
return new MTPNetworker(dcID, authKey, authKeyID, serverSalt, transport, options);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2,7 +2,7 @@ import MTTransport from './transport';
|
|||||||
|
|
||||||
//import abridgetPacketCodec from './abridged';
|
//import abridgetPacketCodec from './abridged';
|
||||||
import intermediatePacketCodec from './intermediate';
|
import intermediatePacketCodec from './intermediate';
|
||||||
import {MTPNetworker} from '../networker';
|
import MTPNetworker from '../networker';
|
||||||
import { logger, LogLevels } from '../../logger';
|
import { logger, LogLevels } from '../../logger';
|
||||||
import Obfuscation from './obfuscation';
|
import Obfuscation from './obfuscation';
|
||||||
|
|
||||||
|
@ -17,6 +17,7 @@ if(devMode) {
|
|||||||
const opts = {
|
const opts = {
|
||||||
MTPROTO_WORKER: true,
|
MTPROTO_WORKER: true,
|
||||||
MTPROTO_HTTP: false,
|
MTPROTO_HTTP: false,
|
||||||
|
MTPROTO_HTTP_UPLOAD: true,
|
||||||
DEBUG: devMode,
|
DEBUG: devMode,
|
||||||
version: 3,
|
version: 3,
|
||||||
"ifdef-verbose": devMode, // add this for verbose output
|
"ifdef-verbose": devMode, // add this for verbose output
|
||||||
|
Loading…
x
Reference in New Issue
Block a user