Pod URL -> pod host. HTTPS is required to make friends.
authorChocobozzz <florian.bigard@gmail.com>
Mon, 14 Nov 2016 19:03:04 +0000 (20:03 +0100)
committerChocobozzz <florian.bigard@gmail.com>
Wed, 16 Nov 2016 19:29:26 +0000 (20:29 +0100)
Reason: in a network with mix http/https pods, https pods won't be able
to play videos from http pod (insecure requests).

24 files changed:
client/src/app/admin/friends/friend-add/friend-add.component.html
client/src/app/admin/friends/friend-add/friend-add.component.ts
client/src/app/admin/friends/friend-list/friend-list.component.html
client/src/app/admin/friends/shared/friend.model.ts
client/src/app/admin/friends/shared/friend.service.ts
client/src/app/shared/forms/form-validators/host.validator.ts [new file with mode: 0644]
client/src/app/shared/forms/form-validators/index.ts
client/src/app/shared/forms/form-validators/url.validator.ts [deleted file]
client/src/app/videos/shared/video.model.ts
client/src/app/videos/video-watch/video-watch.component.html
server/controllers/api/pods.js
server/controllers/api/remote.js
server/helpers/custom-validators/pods.js
server/helpers/custom-validators/videos.js
server/helpers/requests.js
server/initializers/constants.js
server/lib/friends.js
server/middlewares/pods.js
server/middlewares/secure.js
server/middlewares/validators/pods.js
server/middlewares/validators/remote.js
server/models/pods.js
server/models/request.js
server/models/video.js

index 788f3b44d168d5894aabc4316e9079fb898c13ca..62182286007ebf6256bfbfb8ae072356d0963921 100644 (file)
@@ -3,13 +3,13 @@
 <div *ngIf="error" class="alert alert-danger">{{ error }}</div>
 
 <form (ngSubmit)="makeFriends()" [formGroup]="form">
-  <div class="form-group"  *ngFor="let url of urls; let id = index; trackBy:customTrackBy">
-    <label for="username">Url</label>
+  <div class="form-group"  *ngFor="let host of hosts; let id = index; trackBy:customTrackBy">
+    <label for="username">Host</label>
 
     <div class="input-group">
       <input
-        type="text" class="form-control" placeholder="http://domain.com"
-        [id]="'url-' + id" [formControlName]="'url-' + id"
+        type="text" class="form-control" placeholder="domain.tld"
+        [id]="'host-' + id" [formControlName]="'host-' + id"
       />
       <span class="input-group-btn">
         <button *ngIf="displayAddField(id)" (click)="addField()" class="btn btn-default" type="button">+</button>
@@ -17,8 +17,8 @@
       </span>
     </div>
 
-    <div [hidden]="form.controls['url-' + id].valid || form.controls['url-' + id].pristine" class="alert alert-warning">
-      It should be a valid url.
+    <div [hidden]="form.controls['host-' + id].valid || form.controls['host-' + id].pristine" class="alert alert-warning">
+      It should be a valid host.
     </div>
   </div>
 
index 64165a9a5b312547f2771a639a67ffc3407f4662..86b018de25333984059a686a4382639ec61321df 100644 (file)
@@ -2,7 +2,7 @@ import { Component, OnInit } from '@angular/core';
 import { FormControl, FormGroup } from '@angular/forms';
 import { Router } from '@angular/router';
 
-import { validateUrl } from '../../../shared';
+import { validateHost } from '../../../shared';
 import { FriendService } from '../shared';
 
 @Component({
@@ -12,7 +12,7 @@ import { FriendService } from '../shared';
 })
 export class FriendAddComponent implements OnInit {
   form: FormGroup;
-  urls = [ ];
+  hosts = [ ];
   error: string = null;
 
   constructor(private router: Router, private friendService: FriendService) {}
@@ -23,8 +23,8 @@ export class FriendAddComponent implements OnInit {
   }
 
   addField() {
-    this.form.addControl(`url-${this.urls.length}`, new FormControl('', [ validateUrl ]));
-    this.urls.push('');
+    this.form.addControl(`host-${this.hosts.length}`, new FormControl('', [ validateHost ]));
+    this.hosts.push('');
   }
 
   customTrackBy(index: number, obj: any): any {
@@ -32,52 +32,52 @@ export class FriendAddComponent implements OnInit {
   }
 
   displayAddField(index: number) {
-    return index === (this.urls.length - 1);
+    return index === (this.hosts.length - 1);
   }
 
   displayRemoveField(index: number) {
-    return (index !== 0 || this.urls.length > 1) && index !== (this.urls.length - 1);
+    return (index !== 0 || this.hosts.length > 1) && index !== (this.hosts.length - 1);
   }
 
   isFormValid() {
     // Do not check the last input
-    for (let i = 0; i < this.urls.length - 1; i++) {
-      if (!this.form.controls[`url-${i}`].valid) return false;
+    for (let i = 0; i < this.hosts.length - 1; i++) {
+      if (!this.form.controls[`host-${i}`].valid) return false;
     }
 
-    const lastIndex = this.urls.length - 1;
+    const lastIndex = this.hosts.length - 1;
     // If the last input (which is not the first) is empty, it's ok
-    if (this.urls[lastIndex] === '' && lastIndex !== 0) {
+    if (this.hosts[lastIndex] === '' && lastIndex !== 0) {
       return true;
     } else {
-      return this.form.controls[`url-${lastIndex}`].valid;
+      return this.form.controls[`host-${lastIndex}`].valid;
     }
   }
 
   removeField(index: number) {
     // Remove the last control
-    this.form.removeControl(`url-${this.urls.length - 1}`);
-    this.urls.splice(index, 1);
+    this.form.removeControl(`host-${this.hosts.length - 1}`);
+    this.hosts.splice(index, 1);
   }
 
   makeFriends() {
     this.error = '';
 
-    const notEmptyUrls = this.getNotEmptyUrls();
-    if (notEmptyUrls.length === 0) {
-      this.error = 'You need to specify at less 1 url.';
+    const notEmptyHosts = this.getNotEmptyHosts();
+    if (notEmptyHosts.length === 0) {
+      this.error = 'You need to specify at least 1 host.';
       return;
     }
 
-    if (!this.isUrlsUnique(notEmptyUrls)) {
-      this.error = 'Urls need to be unique.';
+    if (!this.isHostsUnique(notEmptyHosts)) {
+      this.error = 'Hosts need to be unique.';
       return;
     }
 
-    const confirmMessage = 'Are you sure to make friends with:\n - ' + notEmptyUrls.join('\n - ');
+    const confirmMessage = 'Are you sure to make friends with:\n - ' + notEmptyHosts.join('\n - ');
     if (!confirm(confirmMessage)) return;
 
-    this.friendService.makeFriends(notEmptyUrls).subscribe(
+    this.friendService.makeFriends(notEmptyHosts).subscribe(
       status => {
         // TODO: extractdatastatus
         // if (status === 409) {
@@ -91,18 +91,18 @@ export class FriendAddComponent implements OnInit {
     );
   }
 
-  private getNotEmptyUrls() {
-    const notEmptyUrls = [];
+  private getNotEmptyHosts() {
+    const notEmptyHosts = [];
 
-    Object.keys(this.form.value).forEach((urlKey) => {
-      const url = this.form.value[urlKey];
-      if (url !== '') notEmptyUrls.push(url);
+    Object.keys(this.form.value).forEach((hostKey) => {
+      const host = this.form.value[hostKey];
+      if (host !== '') notEmptyHosts.push(host);
     });
 
-    return notEmptyUrls;
+    return notEmptyHosts;
   }
 
-  private isUrlsUnique(urls: string[]) {
-    return urls.every(url => urls.indexOf(url) === urls.lastIndexOf(url));
+  private isHostsUnique(hosts: string[]) {
+    return hosts.every(host => hosts.indexOf(host) === hosts.lastIndexOf(host));
   }
 }
index 20b4d12db5a95a081ab71f48007b04c50253680a..4236fc5f60ecb211446e6a5f326f3afeb4389e6e 100644 (file)
@@ -4,7 +4,7 @@
   <thead>
     <tr>
       <th class="table-column-id">ID</th>
-      <th>Url</th>
+      <th>Host</th>
       <th>Score</th>
       <th>Created Date</th>
     </tr>
@@ -13,7 +13,7 @@
   <tbody>
     <tr *ngFor="let friend of friends">
       <td>{{ friend.id }}</td>
-      <td>{{ friend.url }}</td>
+      <td>{{ friend.host }}</td>
       <td>{{ friend.score }}</td>
       <td>{{ friend.createdDate | date: 'medium' }}</td>
     </tr>
index 7cb28f44064be81db58c1a3edb323e1a4704cf68..3c23feebca7fce795a4b690a7022e9b0ff321816 100644 (file)
@@ -1,6 +1,6 @@
 export interface Friend {
   id: string;
-  url: string;
+  host: string;
   score: number;
   createdDate: Date;
 }
index 75826fc17bccac2e7c2388d7997a5aa42db4e1fa..8a1ba6b02d3b84706eb3dc3ebba8e6a35ceef2a4 100644 (file)
@@ -21,9 +21,9 @@ export class FriendService {
                         .catch((res) => this.restExtractor.handleError(res));
   }
 
-  makeFriends(notEmptyUrls) {
+  makeFriends(notEmptyHosts) {
     const body = {
-      urls: notEmptyUrls
+      hosts: notEmptyHosts
     };
 
     return this.authHttp.post(FriendService.BASE_FRIEND_URL + 'makefriends', body)
diff --git a/client/src/app/shared/forms/form-validators/host.validator.ts b/client/src/app/shared/forms/form-validators/host.validator.ts
new file mode 100644 (file)
index 0000000..9cb46d3
--- /dev/null
@@ -0,0 +1,11 @@
+import { FormControl } from '@angular/forms';
+
+export function validateHost(c: FormControl) {
+  let HOST_REGEXP = new RegExp('^(www\.)?[-a-zA-Z0-9@:%._\+~#=]{2,256}\.[a-z]{2,6}\\b([-a-zA-Z0-9@:%_\+.~#?&//=]*)$');
+
+  return HOST_REGEXP.test(c.value) ? null : {
+    validateHost: {
+      valid: false
+    }
+  };
+}
index 1d2ae6f689756265e40684d7d5fbd237abc88ea2..4c6cc66371a77e55dada04af19be3ac932b34fd0 100644 (file)
@@ -1,3 +1,3 @@
-export * from './url.validator';
+export * from './host.validator';
 export * from './user';
 export * from './video';
diff --git a/client/src/app/shared/forms/form-validators/url.validator.ts b/client/src/app/shared/forms/form-validators/url.validator.ts
deleted file mode 100644 (file)
index 67163b4..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
-import { FormControl } from '@angular/forms';
-
-export function validateUrl(c: FormControl) {
-  let URL_REGEXP = new RegExp('^https?://(www\.)?[-a-zA-Z0-9@:%._\+~#=]{2,256}\.[a-z]{2,6}\\b([-a-zA-Z0-9@:%_\+.~#?&//=]*)$');
-
-  return URL_REGEXP.test(c.value) ? null : {
-    validateUrl: {
-      valid: false
-    }
-  };
-}
index 873c83ff1b90d2e0495435b81c87a0fd6096ef7c..b51a0e9de4561ecb5de27eff159af436e08241bd 100644 (file)
@@ -8,21 +8,12 @@ export class Video {
   isLocal: boolean;
   magnetUri: string;
   name: string;
-  podUrl: string;
+  podHost: string;
   tags: string[];
   thumbnailPath: string;
 
-  private static createByString(author: string, podUrl: string) {
-    let [ host, port ] = podUrl.replace(/^https?:\/\//, '').split(':');
-
-    if (port === '80' || port === '443') {
-      port = '';
-    } else {
-      port = ':' + port;
-    }
-
-
-    return author + '@' + host + port;
+  private static createByString(author: string, podHost: string) {
+    return author + '@' + podHost;
   }
 
   private static createDurationString(duration: number) {
@@ -43,7 +34,7 @@ export class Video {
     isLocal: boolean,
     magnetUri: string,
     name: string,
-    podUrl: string,
+    podHost: string,
     tags: string[],
     thumbnailPath: string
   }) {
@@ -55,11 +46,11 @@ export class Video {
     this.isLocal = hash.isLocal;
     this.magnetUri = hash.magnetUri;
     this.name = hash.name;
-    this.podUrl = hash.podUrl;
+    this.podHost = hash.podHost;
     this.tags = hash.tags;
     this.thumbnailPath = hash.thumbnailPath;
 
-    this.by = Video.createByString(hash.author, hash.podUrl);
+    this.by = Video.createByString(hash.author, hash.podHost);
   }
 
   isRemovableBy(user) {
index f3a41636747ec32f75d84b7f5990585ac10e5067..cb91bae7e33e4c575fb75a5e168053f968a6494c 100644 (file)
@@ -2,7 +2,7 @@
   <div class="alert alert-danger">
     The video load seems to be abnormally long.
     <ul>
-      <li>Maybe the server {{ video.podUrl }} is down :(</li>
+      <li>Maybe the server {{ video.podHost }} is down :(</li>
       <li>
         If not, you can report an issue on
         <a href="https://github.com/Chocobozzz/PeerTube/issues" title="Report an issue">
index 853e0705bcfb47c288ff2572ebf20b95a48f70c3..7857fcee0a14b0181d4b78388838b8b68178f1e9 100644 (file)
@@ -20,14 +20,14 @@ const Pod = mongoose.model('Pod')
 router.get('/', listPods)
 router.post('/',
   validators.podsAdd,
-  podsMiddleware.setBodyUrlPort,
+  podsMiddleware.setBodyHostPort,
   addPods
 )
 router.post('/makefriends',
   oAuth.authenticate,
   admin.ensureIsAdmin,
   validators.makeFriends,
-  podsMiddleware.setBodyUrlsPort,
+  podsMiddleware.setBodyHostsPort,
   makeFriends
 )
 router.get('/quitfriends',
@@ -84,17 +84,17 @@ function addPods (req, res, next) {
 }
 
 function listPods (req, res, next) {
-  Pod.list(function (err, podsUrlList) {
+  Pod.list(function (err, podsList) {
     if (err) return next(err)
 
-    res.json(getFormatedPods(podsUrlList))
+    res.json(getFormatedPods(podsList))
   })
 }
 
 function makeFriends (req, res, next) {
-  const urls = req.body.urls
+  const hosts = req.body.hosts
 
-  friends.makeFriends(urls, function (err) {
+  friends.makeFriends(hosts, function (err) {
     if (err) {
       logger.error('Could not make friends.', { error: err })
       return
@@ -107,11 +107,11 @@ function makeFriends (req, res, next) {
 }
 
 function removePods (req, res, next) {
-  const url = req.body.signature.url
+  const host = req.body.signature.host
 
   waterfall([
     function loadPod (callback) {
-      Pod.loadByUrl(url, callback)
+      Pod.loadByHost(host, callback)
     },
 
     function removePod (pod, callback) {
index 94808693d4558e1be922fe66790597b9a2cbad82..4085deb2d7e46309fc0257e5d1f35271c1e3d6c5 100644 (file)
@@ -30,7 +30,7 @@ module.exports = router
 
 function remoteVideos (req, res, next) {
   const requests = req.body.data
-  const fromUrl = req.body.signature.url
+  const fromHost = req.body.signature.host
 
   // We need to process in the same order to keep consistency
   // TODO: optimization
@@ -40,7 +40,7 @@ function remoteVideos (req, res, next) {
     if (request.type === 'add') {
       addRemoteVideo(videoData, callbackEach)
     } else if (request.type === 'remove') {
-      removeRemoteVideo(videoData, fromUrl, callbackEach)
+      removeRemoteVideo(videoData, fromHost, callbackEach)
     } else {
       logger.error('Unkown remote request type %s.', request.type)
     }
@@ -62,16 +62,16 @@ function addRemoteVideo (videoToCreateData, callback) {
   video.save(callback)
 }
 
-function removeRemoteVideo (videoToRemoveData, fromUrl, callback) {
+function removeRemoteVideo (videoToRemoveData, fromHost, callback) {
   // We need the list because we have to remove some other stuffs (thumbnail etc)
-  Video.listByUrlAndRemoteId(fromUrl, videoToRemoveData.remoteId, function (err, videosList) {
+  Video.listByHostAndRemoteId(fromHost, videoToRemoveData.remoteId, function (err, videosList) {
     if (err) {
-      logger.error('Cannot list videos from url and magnets.', { error: err })
+      logger.error('Cannot list videos from host and magnets.', { error: err })
       return callback(err)
     }
 
     if (videosList.length === 0) {
-      logger.error('No remote video was found for this pod.', { magnetUri: videoToRemoveData.magnetUri, podUrl: fromUrl })
+      logger.error('No remote video was found for this pod.', { magnetUri: videoToRemoveData.magnetUri, podHost: fromHost })
     }
 
     each(videosList, function (video, callbackEach) {
index 40f8b5d0b895f4ad8819a0625f14c3727d98113d..0154a242432b1bf43b6bc35ab94bb105864f82e8 100644 (file)
@@ -5,14 +5,14 @@ const validator = require('express-validator').validator
 const miscValidators = require('./misc')
 
 const podsValidators = {
-  isEachUniqueUrlValid
+  isEachUniqueHostValid
 }
 
-function isEachUniqueUrlValid (urls) {
-  return miscValidators.isArray(urls) &&
-    urls.length !== 0 &&
-    urls.every(function (url) {
-      return validator.isURL(url) && urls.indexOf(url) === urls.lastIndexOf(url)
+function isEachUniqueHostValid (hosts) {
+  return miscValidators.isArray(hosts) &&
+    hosts.length !== 0 &&
+    hosts.every(function (host) {
+      return validator.isURL(host) && host.split('://').length === 1 && hosts.indexOf(host) === hosts.lastIndexOf(host)
     })
 }
 
index 45acb7686de1e463d90891a0e4ce829b80983b3c..4a6a623267814bd1727a7417fc76c0e4edf5b672 100644 (file)
@@ -15,7 +15,7 @@ const videosValidators = {
   isVideoDurationValid,
   isVideoMagnetValid,
   isVideoNameValid,
-  isVideoPodUrlValid,
+  isVideoPodHostValid,
   isVideoTagsValid,
   isVideoThumbnailValid,
   isVideoThumbnail64Valid
@@ -33,7 +33,7 @@ function isEachRemoteVideosValid (requests) {
         isVideoDurationValid(video.duration) &&
         isVideoMagnetValid(video.magnet) &&
         isVideoNameValid(video.name) &&
-        isVideoPodUrlValid(video.podUrl) &&
+        isVideoPodHostValid(video.podHost) &&
         isVideoTagsValid(video.tags) &&
         isVideoThumbnail64Valid(video.thumbnailBase64) &&
         isVideoRemoteIdValid(video.remoteId)
@@ -70,7 +70,7 @@ function isVideoNameValid (value) {
   return validator.isLength(value, VIDEOS_CONSTRAINTS_FIELDS.NAME)
 }
 
-function isVideoPodUrlValid (value) {
+function isVideoPodHostValid (value) {
   // TODO: set options (TLD...)
   return validator.isURL(value)
 }
index 95775c981c1a5545d0e82bd45bc4bb48b88770f0..06109ce168d4e8182248590e510aa7950889dc59 100644 (file)
@@ -25,7 +25,7 @@ function makeRetryRequest (params, callback) {
 
 function makeSecureRequest (params, callback) {
   const requestParams = {
-    url: params.toPod.url + params.path
+    url: constants.REMOTE_SCHEME.HTTP + '://' + params.toPod.host + params.path
   }
 
   // Add data with POST requst ?
@@ -34,9 +34,11 @@ function makeSecureRequest (params, callback) {
 
     // Add signature if it is specified in the params
     if (params.sign === true) {
+      const host = constants.CONFIG.WEBSERVER.HOST
+
       requestParams.json.signature = {
-        url: constants.CONFIG.WEBSERVER.URL,
-        signature: peertubeCrypto.sign(constants.CONFIG.WEBSERVER.URL)
+        host,
+        signature: peertubeCrypto.sign(host)
       }
     }
 
index c808aff5f58ee06f9316dbdd6ebfb0fa0ef8e978..d8a13d066930adab55fd196ab7453995b0fa8246 100644 (file)
@@ -14,7 +14,7 @@ const PAGINATION_COUNT_DEFAULT = 15
 
 // Sortable columns per schema
 const SEARCHABLE_COLUMNS = {
-  VIDEOS: [ 'name', 'magnetUri', 'podUrl', 'author', 'tags' ]
+  VIDEOS: [ 'name', 'magnetUri', 'podHost', 'author', 'tags' ]
 }
 
 // Sortable columns per schema
@@ -55,6 +55,7 @@ const CONFIG = {
   }
 }
 CONFIG.WEBSERVER.URL = CONFIG.WEBSERVER.SCHEME + '://' + CONFIG.WEBSERVER.HOSTNAME + ':' + CONFIG.WEBSERVER.PORT
+CONFIG.WEBSERVER.HOST = CONFIG.WEBSERVER.HOSTNAME + ':' + CONFIG.WEBSERVER.PORT
 
 // ---------------------------------------------------------------------------
 
index eafffaab01571676072e5eaa19a62c4a163654ba..eaea040ca9b0829762e594ad328fbf0d021c3e2c 100644 (file)
@@ -6,7 +6,6 @@ const eachSeries = require('async/eachSeries')
 const fs = require('fs')
 const mongoose = require('mongoose')
 const request = require('request')
-const urlUtil = require('url')
 const waterfall = require('async/waterfall')
 
 const constants = require('../initializers/constants')
@@ -44,7 +43,7 @@ function getMyCertificate (callback) {
   fs.readFile(constants.CONFIG.STORAGE.CERT_DIR + 'peertube.pub', 'utf8', callback)
 }
 
-function makeFriends (urls, callback) {
+function makeFriends (hosts, callback) {
   const podsScore = {}
 
   logger.info('Make friends!')
@@ -54,13 +53,13 @@ function makeFriends (urls, callback) {
       return callback(err)
     }
 
-    eachSeries(urls, function (url, callbackEach) {
-      computeForeignPodsList(url, podsScore, callbackEach)
+    eachSeries(hosts, function (host, callbackEach) {
+      computeForeignPodsList(host, podsScore, callbackEach)
     }, function (err) {
       if (err) return callback(err)
 
       logger.debug('Pods scores computed.', { podsScore: podsScore })
-      const podsList = computeWinningPods(urls, podsScore)
+      const podsList = computeWinningPods(hosts, podsScore)
       logger.debug('Pods that we keep.', { podsToKeep: podsList })
 
       makeRequestsToWinningPods(cert, podsList, callback)
@@ -149,45 +148,45 @@ module.exports = friends
 
 // ---------------------------------------------------------------------------
 
-function computeForeignPodsList (url, podsScore, callback) {
-  getForeignPodsList(url, function (err, foreignPodsList) {
+function computeForeignPodsList (host, podsScore, callback) {
+  getForeignPodsList(host, function (err, foreignPodsList) {
     if (err) return callback(err)
 
     if (!foreignPodsList) foreignPodsList = []
 
     // Let's give 1 point to the pod we ask the friends list
-    foreignPodsList.push({ url: url })
+    foreignPodsList.push({ host })
 
     foreignPodsList.forEach(function (foreignPod) {
-      const foreignPodUrl = foreignPod.url
+      const foreignPodHost = foreignPod.host
 
-      if (podsScore[foreignPodUrl]) podsScore[foreignPodUrl]++
-      else podsScore[foreignPodUrl] = 1
+      if (podsScore[foreignPodHost]) podsScore[foreignPodHost]++
+      else podsScore[foreignPodHost] = 1
     })
 
     callback()
   })
 }
 
-function computeWinningPods (urls, podsScore) {
+function computeWinningPods (hosts, podsScore) {
   // Build the list of pods to add
   // Only add a pod if it exists in more than a half base pods
   const podsList = []
-  const baseScore = urls.length / 2
-  Object.keys(podsScore).forEach(function (podUrl) {
+  const baseScore = hosts.length / 2
+  Object.keys(podsScore).forEach(function (podHost) {
     // If the pod is not me and with a good score we add it
-    if (isMe(podUrl) === false && podsScore[podUrl] > baseScore) {
-      podsList.push({ url: podUrl })
+    if (isMe(podHost) === false && podsScore[podHost] > baseScore) {
+      podsList.push({ host: podHost })
     }
   })
 
   return podsList
 }
 
-function getForeignPodsList (url, callback) {
+function getForeignPodsList (host, callback) {
   const path = '/api/' + constants.API_VERSION + '/pods'
 
-  request.get(url + path, function (err, response, body) {
+  request.get(constants.REMOTE_SCHEME.HTTP + '://' + host + path, function (err, response, body) {
     if (err) return callback(err)
 
     try {
@@ -207,26 +206,26 @@ function makeRequestsToWinningPods (cert, podsList, callback) {
 
   eachLimit(podsList, constants.REQUESTS_IN_PARALLEL, function (pod, callbackEach) {
     const params = {
-      url: pod.url + '/api/' + constants.API_VERSION + '/pods/',
+      url: constants.REMOTE_SCHEME.HTTP + '://' + pod.host + '/api/' + constants.API_VERSION + '/pods/',
       method: 'POST',
       json: {
-        url: constants.CONFIG.WEBSERVER.URL,
+        host: constants.CONFIG.WEBSERVER.HOST,
         publicKey: cert
       }
     }
 
     requests.makeRetryRequest(params, function (err, res, body) {
       if (err) {
-        logger.error('Error with adding %s pod.', pod.url, { error: err })
+        logger.error('Error with adding %s pod.', pod.host, { error: err })
         // Don't break the process
         return callbackEach()
       }
 
       if (res.statusCode === 200) {
-        const podObj = new Pod({ url: pod.url, publicKey: body.cert })
+        const podObj = new Pod({ host: pod.host, publicKey: body.cert })
         podObj.save(function (err, podCreated) {
           if (err) {
-            logger.error('Cannot add friend %s pod.', pod.url, { error: err })
+            logger.error('Cannot add friend %s pod.', pod.host, { error: err })
             return callbackEach()
           }
 
@@ -236,7 +235,7 @@ function makeRequestsToWinningPods (cert, podsList, callback) {
           return callbackEach()
         })
       } else {
-        logger.error('Status not 200 for %s pod.', pod.url)
+        logger.error('Status not 200 for %s pod.', pod.host)
         return callbackEach()
       }
     })
@@ -268,14 +267,6 @@ function createRequest (type, endpoint, data, to) {
   })
 }
 
-function isMe (url) {
-  const parsedUrl = urlUtil.parse(url)
-
-  const hostname = parsedUrl.hostname
-  const port = parseInt(parsedUrl.port)
-
-  const myHostname = constants.CONFIG.WEBSERVER.HOSTNAME
-  const myPort = constants.CONFIG.WEBSERVER.PORT
-
-  return hostname === myHostname && port === myPort
+function isMe (host) {
+  return host === constants.CONFIG.WEBSERVER.HOST
 }
index 6e0874a7699833c0d8ed7804c90926c8c1aa61f9..487ea1259e6a403a149e5fb28a5a40d6671b9db5 100644 (file)
@@ -1,38 +1,36 @@
 'use strict'
 
-const urlModule = require('url')
-
-const logger = require('../helpers/logger')
+const constants = require('../initializers/constants')
 
 const podsMiddleware = {
-  setBodyUrlsPort,
-  setBodyUrlPort
+  setBodyHostsPort,
+  setBodyHostPort
 }
 
-function setBodyUrlsPort (req, res, next) {
-  for (let i = 0; i < req.body.urls.length; i++) {
-    const urlWithPort = getUrlWithPort(req.body.urls[i])
+function setBodyHostsPort (req, res, next) {
+  for (let i = 0; i < req.body.hosts.length; i++) {
+    const hostWithPort = getHostWithPort(req.body.hosts[i])
 
     // Problem with the url parsing?
-    if (urlWithPort === null) {
+    if (hostWithPort === null) {
       return res.sendStatus(500)
     }
 
-    req.body.urls[i] = urlWithPort
+    req.body.hosts[i] = hostWithPort
   }
 
   return next()
 }
 
-function setBodyUrlPort (req, res, next) {
-  const urlWithPort = getUrlWithPort(req.body.url)
+function setBodyHostPort (req, res, next) {
+  const hostWithPort = getHostWithPort(req.body.host)
 
   // Problem with the url parsing?
-  if (urlWithPort === null) {
+  if (hostWithPort === null) {
     return res.sendStatus(500)
   }
 
-  req.body.url = urlWithPort
+  req.body.host = hostWithPort
 
   return next()
 }
@@ -43,20 +41,16 @@ module.exports = podsMiddleware
 
 // ---------------------------------------------------------------------------
 
-function getUrlWithPort (url) {
-  const urlObj = urlModule.parse(url)
-
-  // Add the port if it is not specified
-  if (urlObj.port === null) {
-    if (urlObj.protocol === 'http:') {
-      return url + ':80'
-    } else if (urlObj.protocol === 'https:') {
-      return url + ':443'
-    } else {
-      logger.error('Unknown url protocol: ' + urlObj.protocol)
-      return null
-    }
+function getHostWithPort (host) {
+  const splitted = host.split(':')
+
+  console.log(splitted)
+  // The port was not specified
+  if (splitted.length === 1) {
+    if (constants.REMOTE_SCHEME.HTTP === 'https') return host + ':443'
+
+    return host + ':80'
   }
 
-  return url
+  return host
 }
index 58f824d14cbb4561f00d42c42d2c214e9640ea03..fd5bc51d6423babddf197cdbc797d287de77d5ff 100644 (file)
@@ -12,27 +12,27 @@ const secureMiddleware = {
 }
 
 function checkSignature (req, res, next) {
-  const url = req.body.signature.url
-  Pod.loadByUrl(url, function (err, pod) {
+  const host = req.body.signature.host
+  Pod.loadByHost(host, function (err, pod) {
     if (err) {
-      logger.error('Cannot get signed url in decryptBody.', { error: err })
+      logger.error('Cannot get signed host in decryptBody.', { error: err })
       return res.sendStatus(500)
     }
 
     if (pod === null) {
-      logger.error('Unknown pod %s.', url)
+      logger.error('Unknown pod %s.', host)
       return res.sendStatus(403)
     }
 
-    logger.debug('Decrypting body from %s.', url)
+    logger.debug('Decrypting body from %s.', host)
 
-    const signatureOk = peertubeCrypto.checkSignature(pod.publicKey, url, req.body.signature.signature)
+    const signatureOk = peertubeCrypto.checkSignature(pod.publicKey, host, req.body.signature.signature)
 
     if (signatureOk === true) {
       return next()
     }
 
-    logger.error('Signature is not okay in decryptBody for %s.', req.body.signature.url)
+    logger.error('Signature is not okay in decryptBody for %s.', req.body.signature.host)
     return res.sendStatus(403)
   })
 }
index fd3d1e2f243375ab5a2b52ccf07c330614b45d28..4f8bad2f9610cd0ce311b43b4b0933d4d78e04ed 100644 (file)
@@ -10,7 +10,7 @@ const validatorsPod = {
 }
 
 function makeFriends (req, res, next) {
-  req.checkBody('urls', 'Should have an array of unique urls').isEachUniqueUrlValid()
+  req.checkBody('hosts', 'Should have an array of unique hosts').isEachUniqueHostValid()
 
   logger.debug('Checking makeFriends parameters', { parameters: req.body })
 
@@ -32,7 +32,7 @@ function makeFriends (req, res, next) {
 }
 
 function podsAdd (req, res, next) {
-  req.checkBody('url', 'Should have an url').notEmpty().isURL({ require_protocol: true })
+  req.checkBody('host', 'Should have an host').notEmpty().isURL()
   req.checkBody('publicKey', 'Should have a public key').notEmpty()
 
   // TODO: check we don't have it already
index 8c29ef8ca40c63407c4353f1a0a3a1f610a435a9..c6455e678027a1e58bfd1594e778014b64f01dbb 100644 (file)
@@ -27,10 +27,10 @@ function remoteVideos (req, res, next) {
 }
 
 function signature (req, res, next) {
-  req.checkBody('signature.url', 'Should have a signature url').isURL()
+  req.checkBody('signature.host', 'Should have a signature host').isURL()
   req.checkBody('signature.signature', 'Should have a signature').notEmpty()
 
-  logger.debug('Checking signature parameters', { parameters: { signatureUrl: req.body.signature.url } })
+  logger.debug('Checking signature parameters', { parameters: { signatureHost: req.body.signature.host } })
 
   checkErrors(req, res, next)
 }
index 6ab018c1ccc0d107323d573f74960b00453abeb4..49c73472abd6a2e8073ee755edaf02b4739a3e61 100644 (file)
@@ -12,7 +12,7 @@ const Video = mongoose.model('Video')
 // ---------------------------------------------------------------------------
 
 const PodSchema = mongoose.Schema({
-  url: String,
+  host: String,
   publicKey: String,
   score: { type: Number, max: constants.FRIEND_SCORE.MAX },
   createdDate: {
@@ -21,8 +21,7 @@ const PodSchema = mongoose.Schema({
   }
 })
 
-// TODO: set options (TLD...)
-PodSchema.path('url').validate(validator.isURL)
+PodSchema.path('host').validate(validator.isURL)
 PodSchema.path('publicKey').required(true)
 PodSchema.path('score').validate(function (value) { return !isNaN(value) })
 
@@ -37,14 +36,14 @@ PodSchema.statics = {
   listAllIds,
   listBadPods,
   load,
-  loadByUrl,
+  loadByHost,
   removeAll
 }
 
 PodSchema.pre('save', function (next) {
   const self = this
 
-  Pod.loadByUrl(this.url, function (err, pod) {
+  Pod.loadByHost(this.host, function (err, pod) {
     if (err) return next(err)
 
     if (pod) return next(new Error('Pod already exists.'))
@@ -56,7 +55,7 @@ PodSchema.pre('save', function (next) {
 
 PodSchema.pre('remove', function (next) {
   // Remove the videos owned by this pod too
-  Video.listByUrl(this.url, function (err, videos) {
+  Video.listByHost(this.host, function (err, videos) {
     if (err) return next(err)
 
     each(videos, function (video, callbackEach) {
@@ -72,7 +71,7 @@ const Pod = mongoose.model('Pod', PodSchema)
 function toFormatedJSON () {
   const json = {
     id: this._id,
-    url: this.url,
+    host: this.host,
     score: this.score,
     createdDate: this.createdDate
   }
@@ -111,8 +110,8 @@ function load (id, callback) {
   return this.findById(id, callback)
 }
 
-function loadByUrl (url, callback) {
-  return this.findOne({ url: url }, callback)
+function loadByHost (host, callback) {
+  return this.findOne({ host }, callback)
 }
 
 function removeAll (callback) {
index f5eec2134388f98e1af6523fbf44dfa2ebee48cf..59bf440feb9d9fb8c45a33451dc55a1ae6c8109f 100644 (file)
@@ -121,7 +121,7 @@ function makeRequest (toPod, requestEndpoint, requestsToMake, callback) {
     if (err || (res.statusCode !== 200 && res.statusCode !== 201 && res.statusCode !== 204)) {
       logger.error(
         'Error sending secure request to %s pod.',
-        toPod.url,
+        toPod.host,
         {
           error: err || new Error('Status code not 20x : ' + res.statusCode)
         }
index 0da2cb8ab5f5a9056236bfa785d662788ca62997..6d3fa3fb83be13618a91271e8a7513b0ac98bbb9 100644 (file)
@@ -28,10 +28,9 @@ const VideoSchema = mongoose.Schema({
   magnet: {
     infoHash: String
   },
-  podUrl: String,
+  podHost: String,
   author: String,
   duration: Number,
-  thumbnail: String,
   tags: [ String ],
   createdDate: {
     type: Date,
@@ -41,14 +40,9 @@ const VideoSchema = mongoose.Schema({
 
 VideoSchema.path('name').validate(customVideosValidators.isVideoNameValid)
 VideoSchema.path('description').validate(customVideosValidators.isVideoDescriptionValid)
-VideoSchema.path('podUrl').validate(customVideosValidators.isVideoPodUrlValid)
+VideoSchema.path('podHost').validate(customVideosValidators.isVideoPodHostValid)
 VideoSchema.path('author').validate(customVideosValidators.isVideoAuthorValid)
 VideoSchema.path('duration').validate(customVideosValidators.isVideoDurationValid)
-// The tumbnail can be the path or the data in base 64
-// The pre save hook will convert the base 64 data in a file on disk and replace the thumbnail key by the filename
-VideoSchema.path('thumbnail').validate(function (value) {
-  return customVideosValidators.isVideoThumbnailValid(value) || customVideosValidators.isVideoThumbnail64Valid(value)
-})
 VideoSchema.path('tags').validate(customVideosValidators.isVideoTagsValid)
 
 VideoSchema.methods = {
@@ -65,8 +59,8 @@ VideoSchema.methods = {
 VideoSchema.statics = {
   getDurationFromFile,
   listForApi,
-  listByUrlAndRemoteId,
-  listByUrl,
+  listByHostAndRemoteId,
+  listByHost,
   listOwned,
   listOwnedByAuthor,
   listRemotes,
@@ -107,7 +101,7 @@ VideoSchema.pre('save', function (next) {
 
   if (video.isOwned()) {
     const videoPath = pathUtils.join(constants.CONFIG.STORAGE.VIDEOS_DIR, video.getVideoFilename())
-    this.podUrl = constants.CONFIG.WEBSERVER.HOSTNAME + ':' + constants.CONFIG.WEBSERVER.PORT
+    this.podHost = constants.CONFIG.WEBSERVER.HOST
 
     tasks.push(
       // TODO: refractoring
@@ -160,8 +154,8 @@ function generateMagnetUri () {
     baseUrlHttp = constants.CONFIG.WEBSERVER.URL
     baseUrlWs = constants.CONFIG.WEBSERVER.WS + '://' + constants.CONFIG.WEBSERVER.HOSTNAME + ':' + constants.CONFIG.WEBSERVER.PORT
   } else {
-    baseUrlHttp = constants.REMOTE_SCHEME.HTTP + '://' + this.podUrl
-    baseUrlWs = constants.REMOTE_SCHEME.WS + this.podUrl
+    baseUrlHttp = constants.REMOTE_SCHEME.HTTP + '://' + this.podHost
+    baseUrlWs = constants.REMOTE_SCHEME.WS + this.podHost
   }
 
   const xs = baseUrlHttp + constants.STATIC_PATHS.TORRENTS + this.getTorrentName()
@@ -215,7 +209,7 @@ function toFormatedJSON () {
     id: this._id,
     name: this.name,
     description: this.description,
-    podUrl: this.podUrl,
+    podHost: this.podHost,
     isLocal: this.isOwned(),
     magnetUri: this.generateMagnetUri(),
     author: this.author,
@@ -249,7 +243,7 @@ function toRemoteJSON (callback) {
       thumbnailBase64: new Buffer(thumbnailData).toString('base64'),
       tags: self.tags,
       createdDate: self.createdDate,
-      podUrl: self.podUrl
+      podHost: self.podHost
     }
 
     return callback(null, remoteVideo)
@@ -271,12 +265,12 @@ function listForApi (start, count, sort, callback) {
   return modelUtils.listForApiWithCount.call(this, query, start, count, sort, callback)
 }
 
-function listByUrlAndRemoteId (fromUrl, remoteId, callback) {
-  this.find({ podUrl: fromUrl, remoteId: remoteId }, callback)
+function listByHostAndRemoteId (fromHost, remoteId, callback) {
+  this.find({ podHost: fromHost, remoteId: remoteId }, callback)
 }
 
-function listByUrl (fromUrl, callback) {
-  this.find({ podUrl: fromUrl }, callback)
+function listByHost (fromHost, callback) {
+  this.find({ podHost: fromHost }, callback)
 }
 
 function listOwned (callback) {