RobotWebTools / web_video_server

HTTP Streaming of ROS Image Topics in Multiple Formats
http://ros.org/wiki/web_video_server
Other
270 stars 188 forks source link

DOMException (cross origin) Error when using point cloud in ros3djs from depthcloud_encoder mjpeg encoder. #91

Open oka1125 opened 5 years ago

oka1125 commented 5 years ago

I can see the image being published at http://localhost:9999/stream?topic=depthcloud_encoded&type=mjpeg.

But whenever I try to use this url in the depthcloud node:

depthCloud = new ROS3D.DepthCloud({
   url : 'http://localhost:9999/stream?topic=depthcloud_encoded&type=mjpeg',
   streamType : 'mjpeg',
   f : 525.0
 });

I get the following error:

`ros3d.js:20172 THREE.WebGLState: DOMException: Failed to execute 'texImage2D' on 'WebGLRenderingContext': The image element contains cross-origin data, and may not be loaded.`

Then the pointcloud does not appear in ros3d.js panel.

oka1125 commented 5 years ago

This issue is related to ros3djs's issue 173.

https://github.com/RobotWebTools/ros3djs/issues/173

oka1125 commented 5 years ago

This could possibly be a CORS issue.

ROS3D.DepthCloud in ros3d.js, "video.crossOrigin=anonymous" is specified. However, the web_video_server's mjpeg stream may not response enough 'Access-Control' specification.

curl -I http://localhost:9999/stream?topic=/depthcloud_encoded&type=mjpeg

HTTP/1.0 200 OK
Connection: close
Server: web_video_server
Cache-Control: no-cache, no-store, must-revalidate, pre-check=0, post-check=0, max-age=0
Pragma: no-cache
Content-type: multipart/x-mixed-replace;boundary=boundarydonotcross
Access-Control-Allow-Origin: *

After I edit web_video_server package's multipart_stream.cpp as follows (add some 'Access-Control-' tags) and rebuild, DOMException(cross-origin) no longer occured in ros3d.js.

void MultipartStream::sendInitialHeader() {
  async_web_server_cpp::HttpReply::builder(async_web_server_cpp::HttpReply::ok).header("Connection", "close").header(
      "Server", "web_video_server").header("Cache-Control",
                                           "no-cache, no-store, must-revalidate, pre-check=0, post-check=0, max-age=0").header(
      "Pragma", "no-cache").header("Content-type", "multipart/x-mixed-replace;boundary="+boundry_).header(
      "Access-Control-Allow-Origin", "*").header("Access-Control-Allow-Methods", "GET,POST,PUT,DELETE,HEAD,OPTIONS").header(
      "Access-Control-Allow-Headers", "Origin, Authorization, Accept, Content-Type").header("Access-Control-Max-Age", "3600").write(connection_);
  connection_->write("--"+boundry_+"\r\n");
}

void MultipartStream::sendPartHeader(const ros::Time &time, const std::string& type, size_t payload_size) {
  char stamp[20];
  sprintf(stamp, "%.06lf", time.toSec());
  boost::shared_ptr<std::vector<async_web_server_cpp::HttpHeader> > headers(
      new std::vector<async_web_server_cpp::HttpHeader>());
  headers->push_back(async_web_server_cpp::HttpHeader("Content-type", type));
  headers->push_back(async_web_server_cpp::HttpHeader("X-Timestamp", stamp));
  headers->push_back(async_web_server_cpp::HttpHeader("Access-Control-Allow-Origin", "*"));
  headers->push_back(async_web_server_cpp::HttpHeader("Access-Control-Allow-Methods", "GET,POST,PUT,DELETE,HEAD,OPTIONS"));
  headers->push_back(async_web_server_cpp::HttpHeader("Access-Control-Allow-Headers", "Origin, Authorization, Accept, Content-Type"));
  headers->push_back(async_web_server_cpp::HttpHeader("Access-Control-Max-Age", "3600"));
  headers->push_back(
      async_web_server_cpp::HttpHeader("Content-Length", boost::lexical_cast<std::string>(payload_size)));
  connection_->write(async_web_server_cpp::HttpReply::to_buffers(*headers), headers);
}

Then, the HTTP HEADER becomes as follows,

curl -I http://localhost:9999/stream?topic=/depthcloud_encoded&type=mjpeg

HTTP/1.0 200 OK
Connection: close
Server: web_video_server
Cache-Control: no-cache, no-store, must-revalidate, pre-check=0, post-check=0, max-age=0
Pragma: no-cache
Content-type: multipart/x-mixed-replace;boundary=boundarydonotcross
Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: GET,POST,PUT,DELETE,HEAD,OPTIONS
Access-Control-Allow-Headers: Origin, Authorization, Accept, Content-Type
Access-Control-Max-Age: 3600