问:
OAuth LTI Error: Request not validating?
I am trying to upgrade a legacy app to use the 2.2 version of the LTI ruby gem.

Currently, I cannot get Oauth requests to validate using the following:

```<code>authenticator = IMS::LTI::Services::MessageAuthenticator.new(@request.url, @params, secret)
authenticator.valid_signature?
</code>```

I'm not sure what is causing this, as it should be a valid request, as far as I can tell. Here are dumps of the variables involved:

App 9783 stdout: --- OAUTH Key ====> ocill-lti-key
App 9783 stdout: --- OAUTH Secret ====> REDACTED!
App 9783 stdout: --- REQUEST URL https://lrc-tesuto.lrc.lsa.umich.edu/ocill/launch/create
App 9783 stdout: --- REQUEST PARAMS {"oauth_consumer_key"=>"ocill-lti-key", "oauth_signature_method"=>"HMAC-SHA1", "oauth_timestamp"=>"1510067228", "oauth_nonce"=>"70h3qDQemquvfZeKZ03OIJt5Me06hmoUuA4DEscIgQ", "oauth_version"=>"1.0", "context_id"=>"de25c863939f3cacfc02480738d072d95597842c", "context_label"=>"johnathb Sandbox", "context_title"=>"A Canvas training course for johnathb", "custom_canvas_assignment_points_possible"=>"10", "custom_canvas_assignment_title"=>"OCILL Staging Test", "custom_canvas_enrollment_state"=>"active", "ext_ims_lis_basic_outcome_url"=>"https://umich.instructure.com/api/lti/v1/tools/10530/ext_grade_passback", "ext_lti_assignment_id"=>"f9139721-be1f-473a-91b5-6a08a386074c", "ext_outcome_data_values_accepted"=>"url,text", "ext_outcome_result_total_score_accepted"=>"true", "ext_outcomes_tool_placement_url"=>"https://umich.instructure.com/api/lti/v1/turnitin/outcomes_placement/10530", "ext_roles"=>"urn:lti:instrole:ims/lis/Administrator,urn:lti:instrole:ims/lis/Instructor,urn:lti:instrole:ims/lis/Student,urn:lti:role:ims/lis/Instructor,urn:lti:sysrole:ims/lis/User", "launch_presentation_document_target"=>"iframe", "launch_presentation_locale"=>"en", "launch_presentation_return_url"=>"https://umich.instructure.com/courses/56125/external_content/success/external_tool_redirect", "lis_outcome_service_url"=>"https://umich.instructure.com/api/lti/v1/tools/10530/grade_passback", "lti_message_type"=>"basic-lti-launch-request", "lti_version"=>"LTI-1p0", "oauth_callback"=>"about:blank", "resource_link_id"=>"52e0499f9ed929340aec886dd08c7035e45471f5", "resource_link_title"=>"OCILL Staging Test", "roles"=>"Instructor", "tool_consumer_info_product_family_code"=>"canvas", "tool_consumer_info_version"=>"cloud", "tool_consumer_instance_contact_email"=>"notifications@instructure.com", "tool_consumer_instance_guid"=>"7db438071375c02373713c12c73869ff2f470b68.umich.instructure.com", "tool_consumer_instance_name"=>"University of Michigan - Ann Arbor", "user_id"=>"1ec00186b63b783a994fd2d5b7648ba6cdfe9807", "oauth_signature"=>"7jq4lBIBYoMzIeShPZbPNJjOrEs=", "controller"=>"launch", "action"=>"create"}

App 9783 stdout: --- AUTHENTICATOR INSPECT ===> #"ocill-lti-key", "oauth_signature_method"=>"HMAC-SHA1", "oauth_timestamp"=>"1510067228", "oauth_nonce"=>"70h3qDQemquvfZeKZ03OIJt5Me06hmoUuA4DEscIgQ", "oauth_version"=>"1.0", "context_id"=>"de25c863939f3cacfc02480738d072d95597842c", "context_label"=>"johnathb Sandbox", "context_title"=>"A Canvas training course for johnathb", "custom_canvas_assignment_points_possible"=>"10", "custom_canvas_assignment_title"=>"OCILL Staging Test", "custom_canvas_enrollment_state"=>"active", "ext_ims_lis_basic_outcome_url"=>"https://umich.instructure.com/api/lti/v1/tools/10530/ext_grade_passback", "ext_lti_assignment_id"=>"f9139721-be1f-473a-91b5-6a08a386074c", "ext_outcome_data_values_accepted"=>"url,text", "ext_outcome_result_total_score_accepted"=>"true", "ext_outcomes_tool_placement_url"=>"https://umich.instructure.com/api/lti/v1/turnitin/outcomes_placement/10530", "ext_roles"=>"urn:lti:instrole:ims/lis/Administrator,urn:lti:instrole:ims/lis/Instructor,urn:lti:instrole:ims/lis/Student,urn:lti:role:ims/lis/Instructor,urn:lti:sysrole:ims/lis/User", "launch_presentation_document_target"=>"iframe", "launch_presentation_locale"=>"en", "launch_presentation_return_url"=>"https://umich.instructure.com/courses/56125/external_content/success/external_tool_redirect", "lis_outcome_service_url"=>"https://umich.instructure.com/api/lti/v1/tools/10530/grade_passback", "lti_message_type"=>"basic-lti-launch-request", "lti_version"=>"LTI-1p0", "oauth_callback"=>"about:blank", "resource_link_id"=>"52e0499f9ed929340aec886dd08c7035e45471f5", "resource_link_title"=>"OCILL Staging Test", "roles"=>"Instructor", "tool_consumer_info_product_family_code"=>"canvas", "tool_consumer_info_version"=>"cloud", "tool_consumer_instance_contact_email"=>"notifications@instructure.com", "tool_consumer_instance_guid"=>"7db438071375c02373713c12c73869ff2f470b68.umich.instructure.com", "tool_consumer_instance_name"=>"University of Michigan - Ann Arbor", "user_id"=>"1ec00186b63b783a994fd2d5b7648ba6cdfe9807", "oauth_signature"=>"7jq4lBIBYoMzIeShPZbPNJjOrEs=", "controller"=>"launch", "action"=>"create"}, @options={:consumer_key=>"ocill-lti-key", :signature_method=>"HMAC-SHA1", :timestamp=>"1510067228", :nonce=>"70h3qDQemquvfZeKZ03OIJt5Me06hmoUuA4DEscIgQ", :version=>"1.0", :callback=>"about:blank"}, @parsed_params={:context_id=>"de25c863939f3cacfc02480738d072d95597842c", :context_label=>"johnathb Sandbox", :context_title=>"A Canvas training course for johnathb", :custom_canvas_assignment_points_possible=>"10", :custom_canvas_assignment_title=>"OCILL Staging Test", :custom_canvas_enrollment_state=>"active", :ext_ims_lis_basic_outcome_url=>"https://umich.instructure.com/api/lti/v1/tools/10530/ext_grade_passback", :ext_lti_assignment_id=>"f9139721-be1f-473a-91b5-6a08a386074c", :ext_outcome_data_values_accepted=>"url,text", :ext_outcome_result_total_score_accepted=>"true", :ext_outcomes_tool_placement_url=>"https://umich.instructure.com/api/lti/v1/turnitin/outcomes_placement/10530", :ext_roles=>"urn:lti:instrole:ims/lis/Administrator,urn:lti:instrole:ims/lis/Instructor,urn:lti:instrole:ims/lis/Student,urn:lti:role:ims/lis/Instructor,urn:lti:sysrole:ims/lis/User", :launch_presentation_document_target=>"iframe", :launch_presentation_locale=>"en", :launch_presentation_return_url=>"https://umich.instructure.com/courses/56125/external_content/success/external_tool_redirect", :lis_outcome_service_url=>"https://umich.instructure.com/api/lti/v1/tools/10530/grade_passback", :lti_message_type=>"basic-lti-launch-request", :lti_version=>"LTI-1p0", :resource_link_id=>"52e0499f9ed929340aec886dd08c7035e45471f5", :resource_link_title=>"OCILL Staging Test", :roles=>"Instructor", :tool_consumer_info_product_family_code=>"canvas", :tool_consumer_info_version=>"cloud", :tool_consumer_instance_contact_email=>"notifications@instructure.com", :tool_consumer_instance_guid=>"7db438071375c02373713c12c73869ff2f470b68.umich.instructure.com", :tool_consumer_instance_name=>"University of Michigan - Ann Arbor", :user_id=>"1ec00186b63b783a994fd2d5b7648ba6cdfe9807", :controller=>"launch", :action=>"create"}, @consumer_key="ocill-lti-key", @Signature="7jq4lBIBYoMzIeShPZbPNJjOrEs=", @secret="REDACTED!", @message=#"10", "custom_canvas_assignment_title"=>"OCILL Staging Test", "custom_canvas_enrollment_state"=>"active"}, @ext_params={"ext_ims_lis_basic_outcome_url"=>"https://umich.instructure.com/api/lti/v1/tools/10530/ext_grade_passback", "ext_lti_assignment_id"=>"f9139721-be1f-473a-91b5-6a08a386074c", "ext_outcome_data_values_accepted"=>"url,text", "ext_outcome_result_total_score_accepted"=>"true", "ext_outcomes_tool_placement_url"=>"https://umich.instructure.com/api/lti/v1/turnitin/outcomes_placement/10530", "ext_roles"=>"urn:lti:instrole:ims/lis/Administrator,urn:lti:instrole:ims/lis/Instructor,urn:lti:instrole:ims/lis/Student,urn:lti:role:ims/lis/Instructor,urn:lti:sysrole:ims/lis/User"}, @unknown_params={"controller"=>"launch", "action"=>"create"}, @oauth_consumer_key="ocill-lti-key", @oauth_signature_method="HMAC-SHA1", @oauth_timestamp="1510067228", @oauth_nonce="70h3qDQemquvfZeKZ03OIJt5Me06hmoUuA4DEscIgQ", @oauth_version="1.0", @context_id="de25c863939f3cacfc02480738d072d95597842c", @context_label="johnathb Sandbox", @context_title="A Canvas training course for johnathb", @launch_presentation_document_target="iframe", @launch_presentation_locale="en", @launch_presentation_return_url="https://umich.instructure.com/courses/56125/external_content/success/external_tool_redirect", @lis_outcome_service_url="https://umich.instructure.com/api/lti/v1/tools/10530/grade_passback", @lti_message_type="basic-lti-launch-request", @lti_version="LTI-1p0", @oauth_callback="about:blank", @resource_link_id="52e0499f9ed929340aec886dd08c7035e45471f5", @resource_link_title="OCILL Staging Test", @roles="Instructor", @tool_consumer_info_product_family_code="canvas", @tool_consumer_info_version="cloud", @tool_consumer_instance_contact_email="notifications@instructure.com", @tool_consumer_instance_guid="7db438071375c02373713c12c73869ff2f470b68.umich.instructure.com", @tool_consumer_instance_name="University of Michigan - Ann Arbor", @user_id="1ec00186b63b783a994fd2d5b7648ba6cdfe9807", @oauth_signature="7jq4lBIBYoMzIeShPZbPNJjOrEs=", @launch_url="https://lrc-tesuto.lrc.lsa.umich.edu/ocill/launch/create">, @simple_oauth_header=#https://lrc-tesuto.lrc.lsa.umich.edu/ocill/launch/create>, @params={:context_id=>"de25c863939f3cacfc02480738d072d95597842c", :context_label=>"johnathb Sandbox", :context_title=>"A Canvas training course for johnathb", :custom_canvas_assignment_points_possible=>"10", :custom_canvas_assignment_title=>"OCILL Staging Test", :custom_canvas_enrollment_state=>"active", :ext_ims_lis_basic_outcome_url=>"https://umich.instructure.com/api/lti/v1/tools/10530/ext_grade_passback", :ext_lti_assignment_id=>"f9139721-be1f-473a-91b5-6a08a386074c", :ext_outcome_data_values_accepted=>"url,text", :ext_outcome_result_total_score_accepted=>"true", :ext_outcomes_tool_placement_url=>"https://umich.instructure.com/api/lti/v1/turnitin/outcomes_placement/10530", :ext_roles=>"urn:lti:instrole:ims/lis/Administrator,urn:lti:instrole:ims/lis/Instructor,urn:lti:instrole:ims/lis/Student,urn:lti:role:ims/lis/Instructor,urn:lti:sysrole:ims/lis/User", :launch_presentation_document_target=>"iframe", :launch_presentation_locale=>"en", :launch_presentation_return_url=>"https://umich.instructure.com/courses/56125/external_content/success/external_tool_redirect", :lis_outcome_service_url=>"https://umich.instructure.com/api/lti/v1/tools/10530/grade_passback", :lti_message_type=>"basic-lti-launch-request", :lti_version=>"LTI-1p0", :resource_link_id=>"52e0499f9ed929340aec886dd08c7035e45471f5", :resource_link_title=>"OCILL Staging Test", :roles=>"Instructor", :tool_consumer_info_product_family_code=>"canvas", :tool_consumer_info_version=>"cloud", :tool_consumer_instance_contact_email=>"notifications@instructure.com", :tool_consumer_instance_guid=>"7db438071375c02373713c12c73869ff2f470b68.umich.instructure.com", :tool_consumer_instance_name=>"University of Michigan - Ann Arbor", :user_id=>"1ec00186b63b783a994fd2d5b7648ba6cdfe9807", :controller=>"launch", :action=>"create"}, @options={:nonce=>"70h3qDQemquvfZeKZ03OIJt5Me06hmoUuA4DEscIgQ", :signature_method=>"HMAC-SHA1", :timestamp=>"1510067228", :version=>"1.0", :consumer_key=>"ocill-lti-key", :callback=>"about:blank", :consumer_secret=>"REDACTED!"}>>

答:
Turns out the issue was that I had extra parameters in my request that were being passed in.

Used the following to generate params for the validator instead:

```<code>params = request.query_parameters.merge(request.request_parameters)
</code>```

Body:
I am trying to upgrade a legacy app to use the 2.2 version of the LTI ruby gem.

Currently, I cannot get Oauth requests to validate using the following:

authenticator = IMS::LTI::Services::MessageAuthenticator.new(@request.url, @params, secret)
authenticator.valid_signature?

I'm not sure what is causing this, as it should be a valid request, as far as I can tell. Here are dumps of the variables involved:

App 9783 stdout: --- OAUTH Key ====> ocill-lti-key
App 9783 stdout: --- OAUTH Secret ====> REDACTED!
App 9783 stdout: --- REQUEST URL https://lrc-tesuto.lrc.lsa.umich.edu/ocill/launch/create
App 9783 stdout: --- REQUEST PARAMS {"oauth_consumer_key"=>"ocill-lti-key", "oauth_signature_method"=>"HMAC-SHA1", "oauth_timestamp"=>"1510067228", "oauth_nonce"=>"70h3qDQemquvfZeKZ03OIJt5Me06hmoUuA4DEscIgQ", "oauth_version"=>"1.0", "context_id"=>"de25c863939f3cacfc02480738d072d95597842c", "context_label"=>"johnathb Sandbox", "context_title"=>"A Canvas training course for johnathb", "custom_canvas_assignment_points_possible"=>"10", "custom_canvas_assignment_title"=>"OCILL Staging Test", "custom_canvas_enrollment_state"=>"active", "ext_ims_lis_basic_outcome_url"=>"https://umich.instructure.com/api/lti/v1/tools/10530/ext_grade_passback", "ext_lti_assignment_id"=>"f9139721-be1f-473a-91b5-6a08a386074c", "ext_outcome_data_values_accepted"=>"url,text", "ext_outcome_result_total_score_accepted"=>"true", "ext_outcomes_tool_placement_url"=>"https://umich.instructure.com/api/lti/v1/turnitin/outcomes_placement/10530", "ext_roles"=>"urn:lti:instrole:ims/lis/Administrator,urn:lti:instrole:ims/lis/Instructor,urn:lti:instrole:ims/lis/Student,urn:lti:role:ims/lis/Instructor,urn:lti:sysrole:ims/lis/User", "launch_presentation_document_target"=>"iframe", "launch_presentation_locale"=>"en", "launch_presentation_return_url"=>"https://umich.instructure.com/courses/56125/external_content/success/external_tool_redirect", "lis_outcome_service_url"=>"https://umich.instructure.com/api/lti/v1/tools/10530/grade_passback", "lti_message_type"=>"basic-lti-launch-request", "lti_version"=>"LTI-1p0", "oauth_callback"=>"about:blank", "resource_link_id"=>"52e0499f9ed929340aec886dd08c7035e45471f5", "resource_link_title"=>"OCILL Staging Test", "roles"=>"Instructor", "tool_consumer_info_product_family_code"=>"canvas", "tool_consumer_info_version"=>"cloud", "tool_consumer_instance_contact_email"=>"notifications@instructure.com", "tool_consumer_instance_guid"=>"7db438071375c02373713c12c73869ff2f470b68.umich.instructure.com", "tool_consumer_instance_name"=>"University of Michigan - Ann Arbor", "user_id"=>"1ec00186b63b783a994fd2d5b7648ba6cdfe9807", "oauth_signature"=>"7jq4lBIBYoMzIeShPZbPNJjOrEs=", "controller"=>"launch", "action"=>"create"}

App 9783 stdout: --- AUTHENTICATOR INSPECT ===> #"ocill-lti-key", "oauth_signature_method"=>"HMAC-SHA1", "oauth_timestamp"=>"1510067228", "oauth_nonce"=>"70h3qDQemquvfZeKZ03OIJt5Me06hmoUuA4DEscIgQ", "oauth_version"=>"1.0", "context_id"=>"de25c863939f3cacfc02480738d072d95597842c", "context_label"=>"johnathb Sandbox", "context_title"=>"A Canvas training course for johnathb", "custom_canvas_assignment_points_possible"=>"10", "custom_canvas_assignment_title"=>"OCILL Staging Test", "custom_canvas_enrollment_state"=>"active", "ext_ims_lis_basic_outcome_url"=>"https://umich.instructure.com/api/lti/v1/tools/10530/ext_grade_passback", "ext_lti_assignment_id"=>"f9139721-be1f-473a-91b5-6a08a386074c", "ext_outcome_data_values_accepted"=>"url,text", "ext_outcome_result_total_score_accepted"=>"true", "ext_outcomes_tool_placement_url"=>"https://umich.instructure.com/api/lti/v1/turnitin/outcomes_placement/10530", "ext_roles"=>"urn:lti:instrole:ims/lis/Administrator,urn:lti:instrole:ims/lis/Instructor,urn:lti:instrole:ims/lis/Student,urn:lti:role:ims/lis/Instructor,urn:lti:sysrole:ims/lis/User", "launch_presentation_document_target"=>"iframe", "launch_presentation_locale"=>"en", "launch_presentation_return_url"=>"https://umich.instructure.com/courses/56125/external_content/success/external_tool_redirect", "lis_outcome_service_url"=>"https://umich.instructure.com/api/lti/v1/tools/10530/grade_passback", "lti_message_type"=>"basic-lti-launch-request", "lti_version"=>"LTI-1p0", "oauth_callback"=>"about:blank", "resource_link_id"=>"52e0499f9ed929340aec886dd08c7035e45471f5", "resource_link_title"=>"OCILL Staging Test", "roles"=>"Instructor", "tool_consumer_info_product_family_code"=>"canvas", "tool_consumer_info_version"=>"cloud", "tool_consumer_instance_contact_email"=>"notifications@instructure.com", "tool_consumer_instance_guid"=>"7db438071375c02373713c12c73869ff2f470b68.umich.instructure.com", "tool_consumer_instance_name"=>"University of Michigan - Ann Arbor", "user_id"=>"1ec00186b63b783a994fd2d5b7648ba6cdfe9807", "oauth_signature"=>"7jq4lBIBYoMzIeShPZbPNJjOrEs=", "controller"=>"launch", "action"=>"create"}, @options={:consumer_key=>"ocill-lti-key", :signature_method=>"HMAC-SHA1", :timestamp=>"1510067228", :nonce=>"70h3qDQemquvfZeKZ03OIJt5Me06hmoUuA4DEscIgQ", :version=>"1.0", :callback=>"about:blank"}, @parsed_params={:context_id=>"de25c863939f3cacfc02480738d072d95597842c", :context_label=>"johnathb Sandbox", :context_title=>"A Canvas training course for johnathb", :custom_canvas_assignment_points_possible=>"10", :custom_canvas_assignment_title=>"OCILL Staging Test", :custom_canvas_enrollment_state=>"active", :ext_ims_lis_basic_outcome_url=>"https://umich.instructure.com/api/lti/v1/tools/10530/ext_grade_passback", :ext_lti_assignment_id=>"f9139721-be1f-473a-91b5-6a08a386074c", :ext_outcome_data_values_accepted=>"url,text", :ext_outcome_result_total_score_accepted=>"true", :ext_outcomes_tool_placement_url=>"https://umich.instructure.com/api/lti/v1/turnitin/outcomes_placement/10530", :ext_roles=>"urn:lti:instrole:ims/lis/Administrator,urn:lti:instrole:ims/lis/Instructor,urn:lti:instrole:ims/lis/Student,urn:lti:role:ims/lis/Instructor,urn:lti:sysrole:ims/lis/User", :launch_presentation_document_target=>"iframe", :launch_presentation_locale=>"en", :launch_presentation_return_url=>"https://umich.instructure.com/courses/56125/external_content/success/external_tool_redirect", :lis_outcome_service_url=>"https://umich.instructure.com/api/lti/v1/tools/10530/grade_passback", :lti_message_type=>"basic-lti-launch-request", :lti_version=>"LTI-1p0", :resource_link_id=>"52e0499f9ed929340aec886dd08c7035e45471f5", :resource_link_title=>"OCILL Staging Test", :roles=>"Instructor", :tool_consumer_info_product_family_code=>"canvas", :tool_consumer_info_version=>"cloud", :tool_consumer_instance_contact_email=>"notifications@instructure.com", :tool_consumer_instance_guid=>"7db438071375c02373713c12c73869ff2f470b68.umich.instructure.com", :tool_consumer_instance_name=>"University of Michigan - Ann Arbor", :user_id=>"1ec00186b63b783a994fd2d5b7648ba6cdfe9807", :controller=>"launch", :action=>"create"}, @consumer_key="ocill-lti-key", @Signature="7jq4lBIBYoMzIeShPZbPNJjOrEs=", @secret="REDACTED!", @message=#"10", "custom_canvas_assignment_title"=>"OCILL Staging Test", "custom_canvas_enrollment_state"=>"active"}, @ext_params={"ext_ims_lis_basic_outcome_url"=>"https://umich.instructure.com/api/lti/v1/tools/10530/ext_grade_passback", "ext_lti_assignment_id"=>"f9139721-be1f-473a-91b5-6a08a386074c", "ext_outcome_data_values_accepted"=>"url,text", "ext_outcome_result_total_score_accepted"=>"true", "ext_outcomes_tool_placement_url"=>"https://umich.instructure.com/api/lti/v1/turnitin/outcomes_placement/10530", "ext_roles"=>"urn:lti:instrole:ims/lis/Administrator,urn:lti:instrole:ims/lis/Instructor,urn:lti:instrole:ims/lis/Student,urn:lti:role:ims/lis/Instructor,urn:lti:sysrole:ims/lis/User"}, @unknown_params={"controller"=>"launch", "action"=>"create"}, @oauth_consumer_key="ocill-lti-key", @oauth_signature_method="HMAC-SHA1", @oauth_timestamp="1510067228", @oauth_nonce="70h3qDQemquvfZeKZ03OIJt5Me06hmoUuA4DEscIgQ", @oauth_version="1.0", @context_id="de25c863939f3cacfc02480738d072d95597842c", @context_label="johnathb Sandbox", @context_title="A Canvas training course for johnathb", @launch_presentation_document_target="iframe", @launch_presentation_locale="en", @launch_presentation_return_url="https://umich.instructure.com/courses/56125/external_content/success/external_tool_redirect", @lis_outcome_service_url="https://umich.instructure.com/api/lti/v1/tools/10530/grade_passback", @lti_message_type="basic-lti-launch-request", @lti_version="LTI-1p0", @oauth_callback="about:blank", @resource_link_id="52e0499f9ed929340aec886dd08c7035e45471f5", @resource_link_title="OCILL Staging Test", @roles="Instructor", @tool_consumer_info_product_family_code="canvas", @tool_consumer_info_version="cloud", @tool_consumer_instance_contact_email="notifications@instructure.com", @tool_consumer_instance_guid="7db438071375c02373713c12c73869ff2f470b68.umich.instructure.com", @tool_consumer_instance_name="University of Michigan - Ann Arbor", @user_id="1ec00186b63b783a994fd2d5b7648ba6cdfe9807", @oauth_signature="7jq4lBIBYoMzIeShPZbPNJjOrEs=", @launch_url="https://lrc-tesuto.lrc.lsa.umich.edu/ocill/launch/create">, @simple_oauth_header=#https://lrc-tesuto.lrc.lsa.umich.edu/ocill/launch/create>, @params={:context_id=>"de25c863939f3cacfc02480738d072d95597842c", :context_label=>"johnathb Sandbox", :context_title=>"A Canvas training course for johnathb", :custom_canvas_assignment_points_possible=>"10", :custom_canvas_assignment_title=>"OCILL Staging Test", :custom_canvas_enrollment_state=>"active", :ext_ims_lis_basic_outcome_url=>"https://umich.instructure.com/api/lti/v1/tools/10530/ext_grade_passback", :ext_lti_assignment_id=>"f9139721-be1f-473a-91b5-6a08a386074c", :ext_outcome_data_values_accepted=>"url,text", :ext_outcome_result_total_score_accepted=>"true", :ext_outcomes_tool_placement_url=>"https://umich.instructure.com/api/lti/v1/turnitin/outcomes_placement/10530", :ext_roles=>"urn:lti:instrole:ims/lis/Administrator,urn:lti:instrole:ims/lis/Instructor,urn:lti:instrole:ims/lis/Student,urn:lti:role:ims/lis/Instructor,urn:lti:sysrole:ims/lis/User", :launch_presentation_document_target=>"iframe", :launch_presentation_locale=>"en", :launch_presentation_return_url=>"https://umich.instructure.com/courses/56125/external_content/success/external_tool_redirect", :lis_outcome_service_url=>"https://umich.instructure.com/api/lti/v1/tools/10530/grade_passback", :lti_message_type=>"basic-lti-launch-request", :lti_version=>"LTI-1p0", :resource_link_id=>"52e0499f9ed929340aec886dd08c7035e45471f5", :resource_link_title=>"OCILL Staging Test", :roles=>"Instructor", :tool_consumer_info_product_family_code=>"canvas", :tool_consumer_info_version=>"cloud", :tool_consumer_instance_contact_email=>"notifications@instructure.com", :tool_consumer_instance_guid=>"7db438071375c02373713c12c73869ff2f470b68.umich.instructure.com", :tool_consumer_instance_name=>"University of Michigan - Ann Arbor", :user_id=>"1ec00186b63b783a994fd2d5b7648ba6cdfe9807", :controller=>"launch", :action=>"create"}, @options={:nonce=>"70h3qDQemquvfZeKZ03OIJt5Me06hmoUuA4DEscIgQ", :signature_method=>"HMAC-SHA1", :timestamp=>"1510067228", :version=>"1.0", :consumer_key=>"ocill-lti-key", :callback=>"about:blank", :consumer_secret=>"REDACTED!"}>>

Body:
Turns out the issue was that I had extra parameters in my request that were being passed in.

Used the following to generate params for the validator instead:

params = request.query_parameters.merge(request.request_parameters)


来源: stackexchange

问:
Rewritepath not working in case of subsites (Sharepoint 2013)
I have created a webservice inorder to sync task with outlook by referring - http://syncspviewoutlook.codeplex.com/.
(This functionality basically syncs current user task with outlook instead of syncing all tasks, whenever connect to Outlook is clicked for a Task List)

I have created an httpmodule inorder to rewritepath (lists.asmx) with  path customservice.asmx  instead of Global.asax file which works fine for parent site(http://example:8081/)
Below is the code for calling my custom webservice.

public void context_BeginRequest(object sender, EventArgs e)
        {

```<code>            HttpContext ctx = HttpContext.Current;
            if (ctx != null)
            {
                string path = ctx.Request.Url.AbsolutePath;
                string userAgent = ctx.Request.UserAgent;
                if (!string.IsNullOrEmpty(userAgent))
                {
                    if (userAgent.Contains("Microsoft Office Outlook") && path.ToLower().IndexOf("_vti_bin/lists.asmx") >= 0)
                    {
                        ctx.RewritePath("/_layouts/15/folder/customservice.asmx");
                    }
                }
            }

    }
</code>```

But when I try to sync tasks in my subsite the rewritepath doesnot seem to work and it is not even throwing any Error. It doesnot call the new customservice.asmx url even though it hits the line - (ctx.RewritePath("/_layouts/15/folder/customservice.asmx");)

Any idea as in why is the original lists.asmx is called and not the new one for subsites(http://example:8081/subsite1/). I did enable Tracing but was unable to find any error.

答:
Was able to resolve the above issue.. as answered here https://social.msdn.microsoft.com/Forums/sharepoint/en-US/cf58fa8d-2806-4732-a556-5996a86d5c10/rewritepath-not-working-in-case-of-subsites?forum=sharepointdevelopment  </p>

<p>I had to change my call from BeginRequest to PostResolveRequestCache </p>

ContentLicense: CC BY-SA 3.0

Body:
I have created a webservice inorder to sync task with outlook by referring - http://syncspviewoutlook.codeplex.com/.
(This functionality basically syncs current user task with outlook instead of syncing all tasks, whenever connect to Outlook is clicked for a Task List)

I have created an httpmodule inorder to rewritepath (lists.asmx) with  path customservice.asmx  instead of Global.asax file which works fine for parent site(http://example:8081/)
Below is the code for calling my custom webservice.

public void context_BeginRequest(object sender, EventArgs e)
        {

            HttpContext ctx = HttpContext.Current;
            if (ctx != null)
            {
                string path = ctx.Request.Url.AbsolutePath;
                string userAgent = ctx.Request.UserAgent;
                if (!string.IsNullOrEmpty(userAgent))
                {
                    if (userAgent.Contains("Microsoft Office Outlook") && path.ToLower().IndexOf("_vti_bin/lists.asmx") >= 0)
                    {
                        ctx.RewritePath("/_layouts/15/folder/customservice.asmx");
                    }
                }
            }

    }

But when I try to sync tasks in my subsite the rewritepath doesnot seem to work and it is not even throwing any Error. It doesnot call the new customservice.asmx url even though it hits the line - (ctx.RewritePath("/_layouts/15/folder/customservice.asmx");)

Any idea as in why is the original lists.asmx is called and not the new one for subsites(http://example:8081/subsite1/). I did enable Tracing but was unable to find any error.

Body:
Was able to resolve the above issue.. as answered here https://social.msdn.microsoft.com/Forums/sharepoint/en-US/cf58fa8d-2806-4732-a556-5996a86d5c10/rewritepath-not-working-in-case-of-subsites?forum=sharepointdevelopment

I had to change my call from BeginRequest to PostResolveRequestCache


问:
JavaScript textarea calculate
The point is that you create a table of your own size. Is there any possible way that when I press "Calc" button it calculates number in this table? Imagine all the rows and columns are filled with random numbers. I want to calculate numbers in same row. First you create a table, then you fill it with values and than you calculate all values between each other.
This is my code:

function createTable() {
  var num_rows = document.getElementById('rows').value;
  var num_cols = document.getElementById('cols').value;
  var theader = '
\n';
  var tbody = '';

  for (var i = 0; i < num_rows; i++) {
    tbody += '
';
    for (var j = 0; j < num_cols; j++) {
      tbody += '';
      tbody += '<input type="text" name="something">';
      tbody += '	'
    }
    tbody += '
\n';
  }
  var tfooter = '
';
  document.getElementById('wrapper').innerHTML = theader + tbody + tfooter;
}```
<pre class="snippet-code-html lang-html prettyprint-override"><code><form name="tablegen">
  <label>col: <input type="text" name="rows" id="rows"/></label><br />
  <label>row: <input type="text" name="cols" id="cols"/></label><br/>
  <input name="generate" type="button" value="Make table!" onclick='createTable();' />
</form>

<div id="wrapper"></div>
<input name="calculate" type="button" value="Calc" /></code>```

答:
Here is an alternate approach that does the multiplication for each row and adds the result to the existing table as a new column.

function createTable() {
  var num_rows = document.getElementById('rows').value;
  var num_cols = document.getElementById('cols').value;
  var theader = '
\n';
  var tbody = '';

  for (var i = 0; i < num_rows; i++) {
    tbody += '
';
    for (var j = 0; j < num_cols; j++) {
      tbody += '';
      tbody += '<input type="text" name="something">';
      tbody += '	'
    }
    tbody += '
\n';
  }
  var tfooter = '
';
  document.getElementById('wrapper').innerHTML = theader + tbody + tfooter;
}

function calculate() {
  // get the table
  var table = document.getElementById("table");
  if (!table) {
    alert("No table made yet");
    return;
  }
  table = table.children[0];
  // loop through rows
  for (var i = 0; i < table.children.length; i++) {
    if (table.children[i].tagName == "TR") {
      var row = table.children[i];

      var result = row.children[0].children[0].value;
      var result_cell = null;

      // loop through cols
      for (var j = 1; j < row.children.length; j++) {
        if (row.children[j].children[0].name != "result") {
          if (!isNaN(parseInt(row.children[j].children[0].value))) {
            result *= parseInt(row.children[j].children[0].value);
          }
        } else {
          result_cell = row.children[j];
        }

      }

      // create new result cell if we don't already have one
      if (result_cell == null) {
        result_cell = document.createElement("TD");
      }
      // update set the value (used an input type)
      result_cell.innerHTML = '<input style="border-color:red;" type="text" name="result" value="' + result + '" readonly>'
      row.appendChild(result_cell);
    }
  }
}```
<pre class="snippet-code-html lang-html prettyprint-override"><code><form name="tablegen">
  <label>row: <input type="text" name="rows" id="rows"/></label><br />
  <label>col: <input type="text" name="cols" id="cols"/></label><br/>
  <input name="generate" type="button" value="Make table!" onclick='createTable();' />
</form>

<div id="wrapper"></div>
<input name="calculate" type="button" value="Calc" onclick='calculate();' /></code>```

Title: JavaScript textarea calculate

Body:
The point is that you create a table of your own size. Is there any possible way that when I press "Calc" button it calculates number in this table? Imagine all the rows and columns are filled with random numbers. I want to calculate numbers in same row. First you create a table, then you fill it with values and than you calculate all values between each other.
This is my code:

function createTable() {
  var num_rows = document.getElementById('rows').value;
  var num_cols = document.getElementById('cols').value;
  var theader = '
\n';
  var tbody = '';

  for (var i = 0; i < num_rows; i++) {
    tbody += '
';
    for (var j = 0; j < num_cols; j++) {
      tbody += '';
      tbody += '<input type="text" name="something">';
      tbody += '	'
    }
    tbody += '
\n';
  }
  var tfooter = '
';
  document.getElementById('wrapper').innerHTML = theader + tbody + tfooter;
}

<form name="tablegen">
  col: <input type="text" name="rows" id="rows"/>

  row: <input type="text" name="cols" id="cols"/>

  <input name="generate" type="button" value="Make table!" onclick='createTable();' />
</form>

<input name="calculate" type="button" value="Calc" />

Body:
Here is an alternate approach that does the multiplication for each row and adds the result to the existing table as a new column.

function createTable() {
  var num_rows = document.getElementById('rows').value;
  var num_cols = document.getElementById('cols').value;
  var theader = '<table border="1" id="table">\n';
  var tbody = '';

  for (var i = 0; i < num_rows; i++) {
    tbody += '<tr>';
    for (var j = 0; j < num_cols; j++) {
      tbody += '<td>';
      tbody += '<input type="text" name="something">';
      tbody += '</td>'
    }
    tbody += '</tr>\n';
  }
  var tfooter = '</table>';
  document.getElementById('wrapper').innerHTML = theader + tbody + tfooter;
}

function calculate() {
  // get the table
  var table = document.getElementById("table");
  if (!table) {
    alert("No table made yet");
    return;
  }
  table = table.children[0];
  // loop through rows
  for (var i = 0; i < table.children.length; i++) {
    if (table.children[i].tagName == "TR") {
      var row = table.children[i];

      var result = row.children[0].children[0].value;
      var result_cell = null;

      // loop through cols
      for (var j = 1; j < row.children.length; j++) {
        if (row.children[j].children[0].name != "result") {
          if (!isNaN(parseInt(row.children[j].children[0].value))) {
            result *= parseInt(row.children[j].children[0].value);
          }
        } else {
          result_cell = row.children[j];
        }

      }

      // create new result cell if we don't already have one
      if (result_cell == null) {
        result_cell = document.createElement("TD");
      }
      // update set the value (used an input type)
      result_cell.innerHTML = '<input style="border-color:red;" type="text" name="result" value="' + result + '" readonly>'
      row.appendChild(result_cell);
    }
  }
}

<form name="tablegen">
  <label>row: <input type="text" name="rows" id="rows"/></label><br />
  <label>col: <input type="text" name="cols" id="cols"/></label><br/>
  <input name="generate" type="button" value="Make table!" onclick='createTable();' />
</form>

<div id="wrapper"></div>
<input name="calculate" type="button" value="Calc" onclick='calculate();' />


问:
Oracle Golden Gate COLSEXCEPT at replication level
I am using golden gate to replicate table from one DB to multiple DB's. The challenging part is that in one DB the table should be replicated full (all table columns), but in the rest of the DBs the table needs to be half replicated, meaning  just a few columns, not all.

Is it possible to have columns exception at the replication level ?

I know that is it possible at the extract level, but this doesn't fit to my scenario.

答: You need to solve this in the REPLICAT side by mapping the necessary columns to the target table using COLMAP. I think USEDEFAULTS will not work in this case for REPLICAT since you mentioned that you need few columns only(Does that mean the table structure is different from SOURCE to TARGET???)</p>


问:
Resend HTTP post before error timeout
I have an Angular 4 project that uses a http post to commands across to our backend. The issue is that sometimes a command can be sent out before the backend is fully up and running. Normally an "ERR_CONNECTION_TIME_OUT" would occur, but our embedded browser for whatever reason holds onto the post for an extremely long time before giving us the error (5 minutes). Since a 5 minute wait is unacceptable, I need to come up with a way to re-send our http post if there isn't a response within 15-30~ seconds

Here is what the current post looks like

```<code>this._http.post(this.sockclientURL, body, { headers: headers })
  .subscribe((res) => {

    let text = res.text();

    if (text.startsWith("ERROR")) {
      console.log("Sockclient Error.");
      if (this.sockclientErrorRetryCount < this.sockclientErrorRetryLimit) {
        console.log("Retrying in 3 seconds.");
        this.sockclientErrorRetryCount++;

        setTimeout(() => {
          this.SendCommand(command, success, fail);
        }, 3000);
      }
      return;
    }
    else {
      this.sockclientErrorRetryCount = 0;
    }

    if (text == "N" || text.startsWith("N ")) {
      this._modalService.alert(this._nackLookup.convert(text));
      if (typeof fail == 'function') {
        fail(text);
      }
    }
    else {

      let deserializedCommand = command.deserialize(text);

      success(deserializedCommand);

      let repeatMillis: number = deserializedCommand.getRepeatMillis();

      if (repeatMillis && repeatMillis > 0) {
        setTimeout(() => {
          this.SendCommand(command, success, fail);
        }, repeatMillis);
      }
    }
  },
  (err) => {
    console.log(err);
    let repeatMillis = 1000;
      setTimeout(() => {
        this.SendCommand(command, success, fail);
      }, repeatMillis);
  });
</code>```

So to re-cap, I have some code in place to re-attempt the command if an error occurs, but our embedded browser holds onto its timeout error for several minutes. I need something to attempt to re-send after 15-30 seconds of no response

答:
Not 100% sure it still works in Angular4, but you should be able to do:

```<code>this
  ._http
  .post(this.sockclientURL, body, { headers: headers })
  .timeout(15000, new Error('timeout exceeded')) // or 30000
  .subscribe((res) => { /* ... */ })
</code>```

Title: Resend HTTP post before error timeout

Body:
I have an Angular 4 project that uses a http post to commands across to our backend. The issue is that sometimes a command can be sent out before the backend is fully up and running. Normally an "ERR_CONNECTION_TIME_OUT" would occur, but our embedded browser for whatever reason holds onto the post for an extremely long time before giving us the error (5 minutes). Since a 5 minute wait is unacceptable, I need to come up with a way to re-send our http post if there isn't a response within 15-30~ seconds

Here is what the current post looks like

this._http.post(this.sockclientURL, body, { headers: headers })
  .subscribe((res) => {

    let text = res.text();

    if (text.startsWith("ERROR")) {
      console.log("Sockclient Error.");
      if (this.sockclientErrorRetryCount < this.sockclientErrorRetryLimit) {
        console.log("Retrying in 3 seconds.");
        this.sockclientErrorRetryCount++;

        setTimeout(() => {
          this.SendCommand(command, success, fail);
        }, 3000);
      }
      return;
    }
    else {
      this.sockclientErrorRetryCount = 0;
    }

    if (text == "N" || text.startsWith("N ")) {
      this._modalService.alert(this._nackLookup.convert(text));
      if (typeof fail == 'function') {
        fail(text);
      }
    }
    else {

      let deserializedCommand = command.deserialize(text);

      success(deserializedCommand);

      let repeatMillis: number = deserializedCommand.getRepeatMillis();

      if (repeatMillis && repeatMillis > 0) {
        setTimeout(() => {
          this.SendCommand(command, success, fail);
        }, repeatMillis);
      }
    }
  },
  (err) => {
    console.log(err);
    let repeatMillis = 1000;
      setTimeout(() => {
        this.SendCommand(command, success, fail);
      }, repeatMillis);
  });

So to re-cap, I have some code in place to re-attempt the command if an error occurs, but our embedded browser holds onto its timeout error for several minutes. I need something to attempt to re-send after 15-30 seconds of no response

Body:
Not 100% sure it still works in Angular4, but you should be able to do:

this
  ._http
  .post(this.sockclientURL, body, { headers: headers })
  .timeout(15000, new Error('timeout exceeded')) // or 30000
  .subscribe((res) => { /* ... */ })


问:
MySQL, puzzled why query is slow, have an index?
I'm puzzled why one of my queries is slow, I have indexes and I've just created a new one.

Yet its still been quite slow and appears in my slow log.

Heres my query...

```<code>  SELECT *,
         COUNT( Word ) AS WordCount
    FROM `keywords`
   WHERE `LetterIdx` = 'A'
GROUP BY Word
ORDER BY Word;
</code>```

Heres the query EXPLAIN'd

Heres my table structure and indexes.

答:
Try a compound index on (LetterIdx, Word)

It should then be able to use the index for both that speciofc where clause, and that specific group by/order by

ContentLicense: CC BY-SA 2.5

Body:
I'm puzzled why one of my queries is slow, I have indexes and I've just created a new one.

Yet its still been quite slow and appears in my slow log.

Heres my query...

  SELECT *,
         COUNT( Word ) AS WordCount
    FROM `keywords`
   WHERE `LetterIdx` = 'A'
GROUP BY Word
ORDER BY Word;

Heres the query EXPLAIN'd

Heres my table structure and indexes.


问:
Wordpress and CI rewrite rule in htaccess
I have installed WordPress in example.com. I have also installed CodeIgniter in ci folder here example.com/ci/, ci is the folder name , register is the controller name and working URL of CI is example.com/ci/register . My base URL starts with https:// .

Now I have one WordPress URL example.com/hotel, hotel is the page that I have created in WordPress admin, it works fine.

I want to run my CI path like example.com/hotel/ci/register, I think we can do it with some rewrite rule so that my URL would look like  example.com/hotel/ci/register. I have added given htaccess for wordpress that redirecting me here example.com/hotel/ci/register. It is showing me 404 error of CI. It means now I am in CI. Now I did following things in routes.php file.

```<code>$route['default_controller'] = 'register';
$route['404_override'] = 'register';
</code>```

Now this URL example.com/hotel/ci/register is working, but this is not right way, next time there will be more controllers then it will not work.

Note: I can not create hotel folder because hotel is a page in the WordPress. If I create hotel folder then WordPress URL example.com/hotel/ will not work. It will redirect WordPress page to the hotel folder. So I have to do it without creating hotel folder. Note example.com=myurl.com .

I need to find another good solution.Any advise or guidance would be greatly appreciated?

Following is my reWrite rule in wordpress htaccess:

```<code># BEGIN WordPress
   <IfModule mod_rewrite.c>
    RewriteEngine On
    RewriteBase /
    RewriteRule ^/?hotel/ci/register(/.*)?$ /ci/$1 [L]
    RewriteRule ^index\.php$ - [L]
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteRule . /index.php [L]
    </IfModule>
# END WordPress
</code>```

And following is my CI htaccess:

```<code><IfModule mod_rewrite.c>
RewriteEngine on
RewriteCond $1 !^(index\.php|resources|robots\.txt)
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php?/$1 [L,QSA]
</IfModule>
</code>```

答:
Interesting problem!  I set up a Docker container with a fresh install of Wordpress and Codeigniter, I created a hotel page in WP, and a Register controller and view in CI, and got testing.  I spent way too long on this, but I did find an answer.

First, your Wordpress .htaccess.  As @tobiv pointed out in a comment, you should not add anything between the BEGIN/END WordPress comments as it might get whacked by a WP update.  Your redirect has to come before the standard WP rules though, so add it at the top of the file:

```<code><IfModule mod_rewrite.c>
RewriteEngine On
RewriteRule ^hotel/ci/register /ci/register [L]
</IfModule>

# BEGIN WordPress
# ... These are the default, unchnaged WP rules
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>
</code>```

<IfModule mod_rewrite.c> and RewriteEngine On are duplicated which seems messy but you do need them, as your new rule has to go first so it processes the request before the WP rules do.

You don't need to modify the Codeigniter .htaccess file, the default one is all you need.  It should be in the root of your Codeigniter installation, ci/.htaccess:

```<code>RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php/$1 [L]
</code>```

At this point https://example.com/hotel/ci/register will show the Codeigniter 404 page.  If you have logging enabled (see config/config.php), and you watch the logfile, you'll see why:

```<code>ERROR - 2017-11-14 17:57:20 --> 404 Page Not Found: Hotel/ci
</code>```

And here's the root of the whole problem.  Since the initial redirect is an internal redirect (means the URL shown in the browser does not change), the URI Codeigniter receives to process is the one still shown in the browser address bar - hotel/ci/register.  Codeigniter will try to handle a request like that in 2 ways:

Look for a matching route in application/config/routes.php

Or look for a controller named application/controllers/Hotel.php, with a method called ci;

In our case there is no Hotel controller, and no route to describe how to handle such a request, so boom, 404.

One simple solution is to create a route to handle this request:

```<code>$route['hotel/ci/register'] = 'register/index';
</code>```

And now https://example.com/hotel/ci/register works!

Notes:

Setting your default route to register ($route['default_controller'] = 'register';) means that https://example.com/ci/ will also show register.  I'm not sure if you want that?  You might run into duplicate-content SEO problems if that URL shows the same as https://example.com/hotel/ci/register, so maybe you want something else, or a 404, there.

Make sure you remove your $route['404_override'] = 'register'; route;

CI base_url is not relevant for this problem, though obviously should be set.  Depending on how you want your links to be I think either http://example.com/ci/ or http://example.com/hotel/ci/ would be right.

I am not quite sure what the purpose of this condition in your CI .htaccess is for:

```<code>RewriteCond $1 !^(index\.php|resources|robots\.txt)
</code>```

The existing default conditions already skip files and directories which exist on disk.  That's what the !-f and !-d conditions mean - "if the requested pattern does not match a file or directory on disk, then do the redirect".

If you have a robots.txt file on disk (in your ci/ dir), and someone requests https://example.com/ci/robots.txt, the !-f condition will fail, and the rewrite is skipped - meaning the request is handled without rewrites and robots.txt is returned successfully.  Same for index.php.  If you have a directory called ci/resources, and someone requests https://example.com/ci/resources, the !-d condition will fail, the redirect is skipped, and the request is successfull.

I'm not sure about your resources part, but maybe you can remove that condition completely.

If you don't need pretty Codeigniter URLs (I mean other than https://example.com/hotel/ci/register, this change won't affect it), and it turns out you don't need that extra condition above, you can get rid of the CI .htaccess completely to simplify things.  To do that, just change the Wordpress RewriteRule to the non-pretty version:

```<code>RewriteRule ^hotel/ci/register /ci/index.php/register [L]
</code>```

And delete your CI .htacces.

Body:
I have installed WordPress in example.com. I have also installed CodeIgniter in ci folder here example.com/ci/, ci is the folder name , register is the controller name and working URL of CI is example.com/ci/register . My base URL starts with https:// .

Now I have one WordPress URL example.com/hotel, hotel is the page that I have created in WordPress admin, it works fine.

I want to run my CI path like example.com/hotel/ci/register, I think we can do it with some rewrite rule so that my URL would look like  example.com/hotel/ci/register. I have added given htaccess for wordpress that redirecting me here example.com/hotel/ci/register. It is showing me 404 error of CI. It means now I am in CI. Now I did following things in routes.php file.

$route['default_controller'] = 'register';
$route['404_override'] = 'register';

Now this URL example.com/hotel/ci/register is working, but this is not right way, next time there will be more controllers then it will not work.

Note: I can not create hotel folder because hotel is a page in the WordPress. If I create hotel folder then WordPress URL example.com/hotel/ will not work. It will redirect WordPress page to the hotel folder. So I have to do it without creating hotel folder. Note example.com=myurl.com .

I need to find another good solution.Any advise or guidance would be greatly appreciated?

Following is my reWrite rule in wordpress htaccess:

# BEGIN WordPress
   <IfModule mod_rewrite.c>
    RewriteEngine On
    RewriteBase /
    RewriteRule ^/?hotel/ci/register(/.*)?$ /ci/$1 [L]
    RewriteRule ^index\.php$ - [L]
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteRule . /index.php [L]
    </IfModule>
# END WordPress

And following is my CI htaccess:

<IfModule mod_rewrite.c>
RewriteEngine on
RewriteCond $1 !^(index\.php|resources|robots\.txt)
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php?/$1 [L,QSA]
</IfModule>

Body:
Interesting problem!  I set up a Docker container with a fresh install of Wordpress and Codeigniter, I created a hotel page in WP, and a Register controller and view in CI, and got testing.  I spent way too long on this, but I did find an answer.

First, your Wordpress .htaccess.  As @tobiv pointed out in a comment, you should not add anything between the BEGIN/END WordPress comments as it might get whacked by a WP update.  Your redirect has to come before the standard WP rules though, so add it at the top of the file:

<IfModule mod_rewrite.c>
RewriteEngine On
RewriteRule ^hotel/ci/register /ci/register [L]
</IfModule>

# BEGIN WordPress
# ... These are the default, unchnaged WP rules
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>

<IfModule mod_rewrite.c> and RewriteEngine On are duplicated which seems messy but you do need them, as your new rule has to go first so it processes the request before the WP rules do.

You don't need to modify the Codeigniter .htaccess file, the default one is all you need.  It should be in the root of your Codeigniter installation, ci/.htaccess:

RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php/$1 [L]

At this point https://example.com/hotel/ci/register will show the Codeigniter 404 page.  If you have logging enabled (see config/config.php), and you watch the logfile, you'll see why:

ERROR - 2017-11-14 17:57:20 --> 404 Page Not Found: Hotel/ci

And here's the root of the whole problem.  Since the initial redirect is an internal redirect (means the URL shown in the browser does not change), the URI Codeigniter receives to process is the one still shown in the browser address bar - hotel/ci/register.  Codeigniter will try to handle a request like that in 2 ways:

Look for a matching route in application/config/routes.php

Or look for a controller named application/controllers/Hotel.php, with a method called ci;

In our case there is no Hotel controller, and no route to describe how to handle such a request, so boom, 404.

One simple solution is to create a route to handle this request:

$route['hotel/ci/register'] = 'register/index';

And now https://example.com/hotel/ci/register works!

Notes:

Setting your default route to register ($route['default_controller'] = 'register';) means that https://example.com/ci/ will also show register.  I'm not sure if you want that?  You might run into duplicate-content SEO problems if that URL shows the same as https://example.com/hotel/ci/register, so maybe you want something else, or a 404, there.

Make sure you remove your $route['404_override'] = 'register'; route;

CI base_url is not relevant for this problem, though obviously should be set.  Depending on how you want your links to be I think either http://example.com/ci/ or http://example.com/hotel/ci/ would be right.

I am not quite sure what the purpose of this condition in your CI .htaccess is for:

RewriteCond $1 !^(index\.php|resources|robots\.txt)

The existing default conditions already skip files and directories which exist on disk.  That's what the !-f and !-d conditions mean - "if the requested pattern does not match a file or directory on disk, then do the redirect".

If you have a robots.txt file on disk (in your ci/ dir), and someone requests https://example.com/ci/robots.txt, the !-f condition will fail, and the rewrite is skipped - meaning the request is handled without rewrites and robots.txt is returned successfully.  Same for index.php.  If you have a directory called ci/resources, and someone requests https://example.com/ci/resources, the !-d condition will fail, the redirect is skipped, and the request is successfull.

I'm not sure about your resources part, but maybe you can remove that condition completely.

If you don't need pretty Codeigniter URLs (I mean other than https://example.com/hotel/ci/register, this change won't affect it), and it turns out you don't need that extra condition above, you can get rid of the CI .htaccess completely to simplify things.  To do that, just change the Wordpress RewriteRule to the non-pretty version:

RewriteRule ^hotel/ci/register /ci/index.php/register [L]

And delete your CI .htacces.


问:
WebRTC iOS: remote video is not shown in iOS client
I am trying to implement WebRTC in an iOS application using GoogleWebRTC pod. i can place a video call between iOS app and a web client, in which case the audio/video works just fine. however when i place a video call between two iOS devices there is no video(audio works). i've checked if there is remote stream and there is.</p>

```<code>let localStream = connectionFactory?.mediaStream(withStreamId: "StreamID")
let audioTrack = connectionFactory?.audioTrack(withTrackId: "AudioTrackID")
let videoSource = connectionFactory?.avFoundationVideoSource(with: mediaConstraint)
let videoTrack = connectionFactory?.videoTrack(with: videoSource!, trackId: "VideoTrackID")
localStream?.addAudioTrack(audioTrack!)
localStream?.addVideoTrack(videoTrack!)
peerConnection?.add(localStream!)
</code>```

答: Could be a lot of things, try going off my example: https://github.com/redfearnk/WebRTCVideoChat</p>

Body:
I am trying to implement WebRTC in an iOS application using GoogleWebRTC pod. i can place a video call between iOS app and a web client, in which case the audio/video works just fine. however when i place a video call between two iOS devices there is no video(audio works). i've checked if there is remote stream and there is.

let localStream = connectionFactory?.mediaStream(withStreamId: "StreamID")
let audioTrack = connectionFactory?.audioTrack(withTrackId: "AudioTrackID")
let videoSource = connectionFactory?.avFoundationVideoSource(with: mediaConstraint)
let videoTrack = connectionFactory?.videoTrack(with: videoSource!, trackId: "VideoTrackID")
localStream?.addAudioTrack(audioTrack!)
localStream?.addVideoTrack(videoTrack!)
peerConnection?.add(localStream!)


问:
Maximum value of timestamp
I am using Python 3.6.0 on Windows 10 x64.

I just found that in time.ctime(seconds), seconds parameter has an implicit maximum value, which is 32536799999, almost equals to 2^34.92135.

Is that the maximum value?

The error message just says it's an invalid number.

>>> import time
>>> time.ctime(32536799999)
>>> 'Mon Jan 19 15:59:59 3001'
>>> time.ctime(32536799999+1)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
OSError: [Errno 22] Invalid argument
```

I googled and looked on Python documentation, but I didn't find anything about it. And I'm going to check this problem on Ubuntu in my lab.

答:
This must be to do with your installation of Python, in version 3.5, I never experience such an error:

```<code>>>> time.ctime(32536799999)
'Mon Jan 19 07:59:59 3001'
>>> time.ctime(32536799999+1)
'Mon Jan 19 08:00:00 3001'
>>> time.ctime(32536799999+9999999999999999)
'Thu Feb 13 01:46:38 316890386'
>>> time.ctime(32536799999+99999999999999999)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
OSError: [Errno 75] Value too large for defined data type
</code>```

and even when I do with a gigantic number, it throws a different error.

Title: Maximum value of timestamp

Body:
I am using Python 3.6.0 on Windows 10 x64.

I just found that in time.ctime(seconds), seconds parameter has an implicit maximum value, which is 32536799999, almost equals to 2^34.92135.

Is that the maximum value?

The error message just says it's an invalid number.

>>> import time
>>> time.ctime(32536799999)
>>> 'Mon Jan 19 15:59:59 3001'
>>> time.ctime(32536799999+1)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
OSError: [Errno 22] Invalid argument

I googled and looked on Python documentation, but I didn't find anything about it. And I'm going to check this problem on Ubuntu in my lab.

Body:
This must be to do with your installation of Python, in version 3.5, I never experience such an error:

>>> time.ctime(32536799999)
'Mon Jan 19 07:59:59 3001'
>>> time.ctime(32536799999+1)
'Mon Jan 19 08:00:00 3001'
>>> time.ctime(32536799999+9999999999999999)
'Thu Feb 13 01:46:38 316890386'
>>> time.ctime(32536799999+99999999999999999)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
OSError: [Errno 75] Value too large for defined data type

and even when I do with a gigantic number, it throws a different error.


问:
Slideshow is properly showed only first time, then it dissapears
I have a problem properly displaying slideshow (which is written in Jquery) when i revisit web page (via router-link)...
So if i press f5 and web page reloads, everything is working properly, but once i click on one link and i'm redirected, half of web page is blank... I belive that problem is because a lot of parts of this application is in jquery code. I bought a template and include it in to my Vuejs2 project

Example of home component

```<code><template>
    <div id="wrapper">
        <HeaderComponent></HeaderComponent>
        <div id="main-content">
            <SlideShow></SlideShow>
        </div>
        <FooterComponent></FooterComponent>
    </div>
</template>

<script>
    import HeaderComponent from './HeaderComponent.vue'
    import SlideShow from './subComponents/SlideShow.vue'
    import FooterComponent from './FooterComponent.vue'

    export default {
        name: 'Home',
        components: {
            'HeaderComponent': HeaderComponent,
            'SlideShow': SlideShow,
            'FooterComponent': FooterComponent
        }
    }
</script>
</code>```

Slideshow component

```<code><template>
    <div class="">
        <div class="rev_slider_wrapper">
            <div id="rev_slider" data-slider-layout="fullscreen" data-slider-thumbnail="true" class="rev_slider">
                <ul>
                    <li><img src="static/img/various/bg-image.png"/></li>
                </ul>
            </div>
        </div>
    </div>
</template>

<script>
    export default {
        name: 'SlideShow'
    }
</script>
</code>```

This is the slider.js included in index.html via  tag

```<code>$(document).ready(function () {
// MAIN VARIABLES INITIALIZATION
    var revapi;

    $(window).resize(function () {
        'use strict';

        if ($('#rev_slider').data('slider-layout') == 'fullscreen' && $('body').hasClass('left-nav')) {
            var windowHeight = $(window).height();
            $('.rev_slider_wrapper, #rev_slider').height(windowHeight);
        }

    });
    (function () {
        'use strict';
        slickCarousel();
        setTimeout(function () {
            revSlider();
            owlCarousel();
        }, 100);
        bxSlider();

        flexslider();
    }());

// REVOLUTION SLIDER
    function revSlider() {
        if ($.fn.revolution && $('#rev_slider').length) {
            var revSliderLayout = $('#rev_slider').data('slider-layout') ? $('#rev_slider').data('slider-layout') : 'auto';
            var revSliderHeight = $('#rev_slider').data('gridheight') ? $('#rev_slider').data('gridheight') : [800, 800, 480, 360];
            var windowHeight = $(window).height();
            if ($('body').hasClass('left-nav')) {
                revSliderLayout = 'auto';
                if ($('#rev_slider').data('slider-layout') == 'fullscreen') {
                    revSliderHeight = windowHeight;
                }
            }
            revapi = $('#rev_slider').show().revolution({
                sliderType: $('#rev_slider').data('slider-type') ? $('#rev_slider').data('slider-type') : 'standard',// standard, hero, carousel
                jsFileLocation: 'static/js/plugins/revolution-slider/revolution/js/',
                sliderLayout: revSliderLayout, // auto, fullscreen, fullwidth
                dottedOverlay: 'none',
                delay: 9000,
                lazyLoad: 'on',
                navigation: {
                    keyboardNavigation: 'on',
                    keyboard_direction: 'horizontal',
                    mouseScrollNavigation: $('#rev_slider').data('nav-mouse') ? $('#rev_slider').data('nav-mouse') : 'off',
                    onHoverStop: 'off',
                    touch: {
                        touchenabled: 'on',
                        swipe_threshold: 75,
                        swipe_min_touches: 1,
                        swipe_direction: 'horizontal',
                        drag_block_vertical: false
                    },
                    arrows: {
                        style: 'zeus',
                        enable: $('#rev_slider').attr('data-nav-arrows') ? false : true,
                        hide_onmobile: false,
                        hide_onleave: false,
                        tmp: $('#rev_slider').data('slider-thumbnail') ? '<div class="tp-title-wrap"><div class="tp-arr-imgholder"></div></div>' : '<div class="tp-title-wrap"></div>',
                        left: {
                            h_align: 'left',
                            v_align: 'center',
                            h_offset: 10,
                            v_offset: 0
                        },
                        right: {
                            h_align: 'right',
                            v_align: 'center',
                            h_offset: 10,
                            v_offset: 0
                        }
                    },
                    bullets: {
                        enable: $('#rev_slider').attr('data-nav-bullets') ? true : false,
                        hide_onmobile: false,
                        style: 'uranus',
                        hide_onleave: false,
                        direction: 'vertical',
                        h_align: $('#rev_slider').data('bullets-align') ? $('#rev_slider').data('bullets-align') : 'left',
                        v_align: 'center',
                        h_offset: 30,
                        v_offset: 0,
                        space: 10,
                        tmp: '<span class="tp-bullet-inner"></span>'
                    }
                },
                carousel: {
                    maxRotation: 5,
                    vary_rotation: "off",
                    minScale: 15,
                    vary_scale: "off",
                    horizontal_align: "center",
                    vertical_align: "center",
                    fadeout: "on",
                    vary_fade: "on",
                    maxVisibleItems: 3,
                    infinity: "off",
                    space: -80,
                    stretch: "off"
                },
                responsiveLevels: $(this).data('responsive') ? $(this).data('responsive') : [1240, 1024, 778, 480],
                gridwidth: $(this).data('gridwidth') ? $(this).data('gridwidth') : [1230, 1024, 767, 480],
                gridheight: revSliderHeight,
                lazyType: 'none',
                parallax: {
                    type: 'mouse',
                    origo: 'slidertop',
                    speed: 2000,
                    levels: [2, 3, 4, 5, 6, 7, 12, 16, 10, 50],
                    disable_onmobile: 'on'
                },
                shadow: 0,
                spinner: 'off',
                stopLoop: 'on',
                stopAfterLoops: 0,
                // stopAtSlide: $('#rev_slider').data('autoplay') ? 0 : 1,
                shuffle: 'off',
                autoHeight: 'off',
                disableProgressBar: 'on',
                hideThumbsOnMobile: 'off',
                hideSliderAtLimit: 0,
                hideCaptionAtLimit: 0,
                hideAllCaptionAtLilmit: 0,
                startWithSlide: 0,
                fallbacks: {
                    simplifyAll: 'off',
                    nextSlideOnWindowFocus: 'off',
                    disableFocusListener: 'off'
                }
            });
            revapi.bind("revolution.slide.onbeforeswap", function (e) {
                if ($('#rev_slider').data('slider-layout') == 'fullscreen' && $('body').hasClass('left-nav')) {
                    var windowHeight = $(window).height();
                    $('.rev_slider_wrapper, #rev_slider').height(windowHeight);
                }
            });
            revapi.bind('revolution.slide.onchange', function (event, data) {
                var logoImg = $('#logo a img');
                var logoLight = $('#logo a').data('logo-light');
                var logoDark = $('#logo a').data('logo-dark');
                var currentSlide = data.slideIndex;
                if (revapi.find('li').eq(data.slideIndex - 1).attr('data-color') === 'dark') {
                    $('body').addClass('transparent-dark');
                    logoImg.attr('src', logoDark);
                }
                if (revapi.find('li').eq(data.slideIndex - 1).attr('data-color') === 'light') {
                    $('body').removeClass('transparent-dark');
                    logoImg.attr('src', logoLight);
                }
            });
            $('body').on('click', '[data-go-to-slide]', function () {
                var goToSlide = $(this).data('go-to-slide');
                revapi.revshowslide(goToSlide);
                return false;
            });

            setTimeout(function () {
                revapi.revredraw();
            }, 400);
        }
    }
});
</code>```

So how to properly reinitialise, reload, do something with this slideshow, so it will be re rendered when i visit page via .

If you need any additional informations please let me know and i will provide. Thank you!

答:
i managed to solve it by calling Jquery function in mounted function
example:

```<code>export default {
        name: 'SlideShow',
        methods: {

        },
        mounted: function () {
            // initial start of slide show
            revSlider();
        }
    }
</code>```

And this is example how my external sliders.js script looks like

```<code>// MAIN VARIABLES INITIALIZATION
    var revapi;

    $(window).resize(function () {
        'use strict';

        if ($('#rev_slider').data('slider-layout') == 'fullscreen' && $('body').hasClass('left-nav')) {
            var windowHeight = $(window).height();
            $('.rev_slider_wrapper, #rev_slider').height(windowHeight);
        }

    });
    (function () {
        'use strict';
        setTimeout(function () {
            revSlider();
        }, 1000);
    }());

    stopAtSlide:1

    // REVOLUTION SLIDER
    function revSlider() {
        if ($.fn.revolution && $('#rev_slider').length) {
            var revSliderLayout = $('#rev_slider').data('slider-layout') ? $('#rev_slider').data('slider-layout') : 'auto';
            ......
</code>```

Body:
I have a problem properly displaying slideshow (which is written in Jquery) when i revisit web page (via router-link)...
So if i press f5 and web page reloads, everything is working properly, but once i click on one link and i'm redirected, half of web page is blank... I belive that problem is because a lot of parts of this application is in jquery code. I bought a template and include it in to my Vuejs2 project

Example of home component

<template>

        <HeaderComponent></HeaderComponent>

            <SlideShow></SlideShow>

        <FooterComponent></FooterComponent>

</template>

Slideshow component

<template>

</template>

This is the slider.js included in index.html via  tag

$(document).ready(function () {
// MAIN VARIABLES INITIALIZATION
    var revapi;

    $(window).resize(function () {
        'use strict';

        if ($('#rev_slider').data('slider-layout') == 'fullscreen' && $('body').hasClass('left-nav')) {
            var windowHeight = $(window).height();
            $('.rev_slider_wrapper, #rev_slider').height(windowHeight);
        }

    });
    (function () {
        'use strict';
        slickCarousel();
        setTimeout(function () {
            revSlider();
            owlCarousel();
        }, 100);
        bxSlider();

        flexslider();
    }());

// REVOLUTION SLIDER
    function revSlider() {
        if ($.fn.revolution && $('#rev_slider').length) {
            var revSliderLayout = $('#rev_slider').data('slider-layout') ? $('#rev_slider').data('slider-layout') : 'auto';
            var revSliderHeight = $('#rev_slider').data('gridheight') ? $('#rev_slider').data('gridheight') : [800, 800, 480, 360];
            var windowHeight = $(window).height();
            if ($('body').hasClass('left-nav')) {
                revSliderLayout = 'auto';
                if ($('#rev_slider').data('slider-layout') == 'fullscreen') {
                    revSliderHeight = windowHeight;
                }
            }
            revapi = $('#rev_slider').show().revolution({
                sliderType: $('#rev_slider').data('slider-type') ? $('#rev_slider').data('slider-type') : 'standard',// standard, hero, carousel
                jsFileLocation: 'static/js/plugins/revolution-slider/revolution/js/',
                sliderLayout: revSliderLayout, // auto, fullscreen, fullwidth
                dottedOverlay: 'none',
                delay: 9000,
                lazyLoad: 'on',
                navigation: {
                    keyboardNavigation: 'on',
                    keyboard_direction: 'horizontal',
                    mouseScrollNavigation: $('#rev_slider').data('nav-mouse') ? $('#rev_slider').data('nav-mouse') : 'off',
                    onHoverStop: 'off',
                    touch: {
                        touchenabled: 'on',
                        swipe_threshold: 75,
                        swipe_min_touches: 1,
                        swipe_direction: 'horizontal',
                        drag_block_vertical: false
                    },
                    arrows: {
                        style: 'zeus',
                        enable: $('#rev_slider').attr('data-nav-arrows') ? false : true,
                        hide_onmobile: false,
                        hide_onleave: false,
                        tmp: $('#rev_slider').data('slider-thumbnail') ? '

' : '

',
                        left: {
                            h_align: 'left',
                            v_align: 'center',
                            h_offset: 10,
                            v_offset: 0
                        },
                        right: {
                            h_align: 'right',
                            v_align: 'center',
                            h_offset: 10,
                            v_offset: 0
                        }
                    },
                    bullets: {
                        enable: $('#rev_slider').attr('data-nav-bullets') ? true : false,
                        hide_onmobile: false,
                        style: 'uranus',
                        hide_onleave: false,
                        direction: 'vertical',
                        h_align: $('#rev_slider').data('bullets-align') ? $('#rev_slider').data('bullets-align') : 'left',
                        v_align: 'center',
                        h_offset: 30,
                        v_offset: 0,
                        space: 10,
                        tmp: ''
                    }
                },
                carousel: {
                    maxRotation: 5,
                    vary_rotation: "off",
                    minScale: 15,
                    vary_scale: "off",
                    horizontal_align: "center",
                    vertical_align: "center",
                    fadeout: "on",
                    vary_fade: "on",
                    maxVisibleItems: 3,
                    infinity: "off",
                    space: -80,
                    stretch: "off"
                },
                responsiveLevels: $(this).data('responsive') ? $(this).data('responsive') : [1240, 1024, 778, 480],
                gridwidth: $(this).data('gridwidth') ? $(this).data('gridwidth') : [1230, 1024, 767, 480],
                gridheight: revSliderHeight,
                lazyType: 'none',
                parallax: {
                    type: 'mouse',
                    origo: 'slidertop',
                    speed: 2000,
                    levels: [2, 3, 4, 5, 6, 7, 12, 16, 10, 50],
                    disable_onmobile: 'on'
                },
                shadow: 0,
                spinner: 'off',
                stopLoop: 'on',
                stopAfterLoops: 0,
                // stopAtSlide: $('#rev_slider').data('autoplay') ? 0 : 1,
                shuffle: 'off',
                autoHeight: 'off',
                disableProgressBar: 'on',
                hideThumbsOnMobile: 'off',
                hideSliderAtLimit: 0,
                hideCaptionAtLimit: 0,
                hideAllCaptionAtLilmit: 0,
                startWithSlide: 0,
                fallbacks: {
                    simplifyAll: 'off',
                    nextSlideOnWindowFocus: 'off',
                    disableFocusListener: 'off'
                }
            });
            revapi.bind("revolution.slide.onbeforeswap", function (e) {
                if ($('#rev_slider').data('slider-layout') == 'fullscreen' && $('body').hasClass('left-nav')) {
                    var windowHeight = $(window).height();
                    $('.rev_slider_wrapper, #rev_slider').height(windowHeight);
                }
            });
            revapi.bind('revolution.slide.onchange', function (event, data) {
                var logoImg = $('#logo a img');
                var logoLight = $('#logo a').data('logo-light');
                var logoDark = $('#logo a').data('logo-dark');
                var currentSlide = data.slideIndex;
                if (revapi.find('li').eq(data.slideIndex - 1).attr('data-color') === 'dark') {
                    $('body').addClass('transparent-dark');
                    logoImg.attr('src', logoDark);
                }
                if (revapi.find('li').eq(data.slideIndex - 1).attr('data-color') === 'light') {
                    $('body').removeClass('transparent-dark');
                    logoImg.attr('src', logoLight);
                }
            });
            $('body').on('click', '[data-go-to-slide]', function () {
                var goToSlide = $(this).data('go-to-slide');
                revapi.revshowslide(goToSlide);
                return false;
            });

            setTimeout(function () {
                revapi.revredraw();
            }, 400);
        }
    }
});

So how to properly reinitialise, reload, do something with this slideshow, so it will be re rendered when i visit page via .

If you need any additional informations please let me know and i will provide. Thank you!

Body:
i managed to solve it by calling Jquery function in mounted function
example:

export default {
        name: 'SlideShow',
        methods: {

        },
        mounted: function () {
            // initial start of slide show
            revSlider();
        }
    }

And this is example how my external sliders.js script looks like

// MAIN VARIABLES INITIALIZATION
    var revapi;

    $(window).resize(function () {
        'use strict';

        if ($('#rev_slider').data('slider-layout') == 'fullscreen' && $('body').hasClass('left-nav')) {
            var windowHeight = $(window).height();
            $('.rev_slider_wrapper, #rev_slider').height(windowHeight);
        }

    });
    (function () {
        'use strict';
        setTimeout(function () {
            revSlider();
        }, 1000);
    }());

    stopAtSlide:1

    // REVOLUTION SLIDER
    function revSlider() {
        if ($.fn.revolution && $('#rev_slider').length) {
            var revSliderLayout = $('#rev_slider').data('slider-layout') ? $('#rev_slider').data('slider-layout') : 'auto';
            ......


问:
Azure Recovery Services Vault is not refreshing backup information
We are evaluating Azure ASR for cloud Backup and Site Recovery.
Started a month ago with Backup services to backup files, folders and SQL servers and everything worked fine, MABS is installed in server A.

We have also added a physical server to Site recovery, installing the Azure site recovery on the same server A. Since then, every dashboard referring to Backup information has not been updated though its clear that GRS Storage is used for backups.

Tried to uninstall/re-install MABS without any success, any ideas? there are no errors in the MABS MMC console.

答: It is not recommended to install backup (MABS) and site recovery on the same machine since both Services are using similar tasks there will be lot of conflicts.</p>

ContentLicense: CC BY-SA 4.0


问:
How do I get a consistent byte representation of strings in C# without manually specifying an encoding?
How do I convert a string to a byte[] in .NET (C#) without manually specifying a specific encoding?

I'm going to encrypt the string. I can encrypt it without converting, but I'd still like to know why encoding comes to play here.

Also, why should encoding even be taken into consideration? Can't I simply get what bytes the string has been stored in? Why is there a dependency on character encodings?

答:
```<code>// C# to convert a string to a byte array.
public static byte[] StrToByteArray(string str)
{
    System.Text.ASCIIEncoding  encoding=new System.Text.ASCIIEncoding();
    return encoding.GetBytes(str);
}

// C# to convert a byte array to a string.
byte [] dBytes = ...
string str;
System.Text.ASCIIEncoding enc = new System.Text.ASCIIEncoding();
str = enc.GetString(dBytes);
</code>```

OwnerDisplayName: Vulcan Eager

LastEditorDisplayName: Dale Ragan

OwnerDisplayName: cyberbobcat


问:
upload files to remote server using multer sftp in express Node js?
I'm trying to upload the files to remote server using multer-sftp in node js. since i'm following the official docs npm multer-sftp. Previously i've uploading the files to Amazon S3 instead of remote server. now i want to upload the files to remote server.

API:

```<code>exports.newFileUpload =  function(req , res , next){
    var storage = sftpStorage({
      sftp: {
        host: 'http://www.port*****es.in/',
        port: 22,
        username: 'username',
        password: 'password'

      },
      destination: function (req, file, cb) {
        cb(null, 'images/')
      },
      filename: function (req, file, cb) {
        cb(null, file.fieldname + '-' + Date.now())
      }
    })

    var upload = multer({ storage: storage }).array('file');

    upload(req,res,function(err){
        logger.debug(JSON.stringify(req.body));
              logger.debug(JSON.stringify(req.files));
          if(err){
               logger.debug("Error Occured", JSON.stringify(err));
               res.json({error_code:1,err_desc:err});

               return;
          } else{
              res.json({error_code:0,err_desc:null});
          }
      });
}
</code>```

While uploading the file, returning the error

```<code>    2017-11-10T02:39:48.297Z - debug: Error Occured {"code":"ENOTFOUND","errno":"ENOTFOUND",
"syscall":"getaddrinfo","hostname":"http://www.port****es.in/","host":"http://www.port****es.in/",
"port":22,"level":"client-socket","storageErrors":[]}
</code>```

And also port no 22 is open in my domain. Awaiting Suggestions,
Thanks in Advance.

答:
For Your Error, there are two possibilities

port no 22 is not open state, also not able to access that folder

Check your folder directory in domain

Uploading Files to remote server using multer-sftp is easy and flexible way.
also we can upload the files to remote server with scp, ssh techniques in node js.

Working Code:

```<code>exports.newFileUpload =  function(req , res , next){
    var storage = sftpStorage({
      sftp: {
        host: 'hostname',
        port: 22,
        username: 'username',
        password: 'password'

      },
      destination: function (req, file, cb) {
        cb(null, 'images/')
      },
      filename: function (req, file, cb) {
        cb(null, file.fieldname + '-' + Date.now())
      }
    })

    var upload = multer({ storage: storage }).array('file');

    upload(req,res,function(err){
        logger.debug(JSON.stringify(req.body));
              logger.debug(JSON.stringify(req.files));
          if(err){
               logger.debug("Error Occured", JSON.stringify(err));
               res.json({error_code:1,err_desc:err});
          } else{
               logger.debug("Files uploaded successfully");
              res.json({error_code:0,err_desc:null});
          }
      });
}
</code>```

Note: When using 'multer-sftp' port no 22 is open in remote server.

Hope it helps !

Body:
I'm trying to upload the files to remote server using multer-sftp in node js. since i'm following the official docs npm multer-sftp. Previously i've uploading the files to Amazon S3 instead of remote server. now i want to upload the files to remote server.

API:

exports.newFileUpload =  function(req , res , next){
    var storage = sftpStorage({
      sftp: {
        host: 'http://www.port*****es.in/',
        port: 22,
        username: 'username',
        password: 'password'

      },
      destination: function (req, file, cb) {
        cb(null, 'images/')
      },
      filename: function (req, file, cb) {
        cb(null, file.fieldname + '-' + Date.now())
      }
    })

    var upload = multer({ storage: storage }).array('file');

    upload(req,res,function(err){
        logger.debug(JSON.stringify(req.body));
              logger.debug(JSON.stringify(req.files));
          if(err){
               logger.debug("Error Occured", JSON.stringify(err));
               res.json({error_code:1,err_desc:err});

               return;
          } else{
              res.json({error_code:0,err_desc:null});
          }
      });
}

While uploading the file, returning the error

    2017-11-10T02:39:48.297Z - debug: Error Occured {"code":"ENOTFOUND","errno":"ENOTFOUND",
"syscall":"getaddrinfo","hostname":"http://www.port****es.in/","host":"http://www.port****es.in/",
"port":22,"level":"client-socket","storageErrors":[]}

And also port no 22 is open in my domain. Awaiting Suggestions,
Thanks in Advance.

Body:
For Your Error, there are two possibilities

port no 22 is not open state, also not able to access that folder

Check your folder directory in domain

Uploading Files to remote server using multer-sftp is easy and flexible way.
also we can upload the files to remote server with scp, ssh techniques in node js.

Working Code:

exports.newFileUpload =  function(req , res , next){
    var storage = sftpStorage({
      sftp: {
        host: 'hostname',
        port: 22,
        username: 'username',
        password: 'password'

      },
      destination: function (req, file, cb) {
        cb(null, 'images/')
      },
      filename: function (req, file, cb) {
        cb(null, file.fieldname + '-' + Date.now())
      }
    })

    var upload = multer({ storage: storage }).array('file');

    upload(req,res,function(err){
        logger.debug(JSON.stringify(req.body));
              logger.debug(JSON.stringify(req.files));
          if(err){
               logger.debug("Error Occured", JSON.stringify(err));
               res.json({error_code:1,err_desc:err});
          } else{
               logger.debug("Files uploaded successfully");
              res.json({error_code:0,err_desc:null});
          }
      });
}

Note: When using 'multer-sftp' port no 22 is open in remote server.

Hope it helps !


问:
MPAndroidChart - How to set range values from BarChart at 2.0.9v?
I´m using MPAndroidChart 2.0.9 version. I would like to set labels on y-axis from 0 to 100 and display always this range, but i can´t find the chart.setYRange() method.</p>

答:
You can try to write this:

```<code>yAxis.setLabelCount(x)
</code>```

This code should give you labels in steps of x, assuming you set a min and max value.

Example of my code:

```<code>YAxis y = mChart.getAxisLeft();
        y.setAxisMaxValue(100);
        y.setAxisMinValue(0);
        y.setLabelCount(6);
</code>```

This will give me labels from 0 to 100 in 6 steps, so: 0-20-40-60-80-100.

Body:
You can try to write this:

yAxis.setLabelCount(x)

This code should give you labels in steps of x, assuming you set a min and max value.

Example of my code:

YAxis y = mChart.getAxisLeft();
        y.setAxisMaxValue(100);
        y.setAxisMinValue(0);
        y.setLabelCount(6);

This will give me labels from 0 to 100 in 6 steps, so: 0-20-40-60-80-100.


问:
send data as string in jquery on handler
i'm wondering if i can send a data for a function as string (instead of object) using the .on handler

i've treid the following :

```<code>$(".news").on("click","news",popUp);
$(".news").on("click",null,"news",popUp);
</code>```

to call this function with "news" as data:

```<code>function popUp (file = "none", opts= {})
{
    alert(file);
}
</code>```

but this is not working ..

i don't want to send data as object because I'm using this function elsewhere and i don't want to change the function structure.

and can i send string data for file and object data for opts ??

答:
Your second call to .on() is correct (if the data is a string, you need to pass a null selector, otherwise the data will be assumed to be the selector for a delegated event).

But the data is in event.data in the handler, not a function argument.

$(".news").on("click", null, "news", popUp);

function popUp(event) {
  alert(event.data);
}```
<pre class="snippet-code-html lang-html prettyprint-override"><code><script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button class="news">Click</button></code>```

If you want to send multiple parameters, use an object.

$(".news").on("click", {
  file: "news",
  options: {
    something: "blah blah"
  }
}, popUp);

function popUp(event) {
  if (event.data) {
    let {
      file: file,
      options: opt
    } = event.data;
    alert(file + " " + opt.something);
  }
}```
<pre class="snippet-code-html lang-html prettyprint-override"><code><script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button class="news">Click</button></code>```

Body:
i'm wondering if i can send a data for a function as string (instead of object) using the .on handler

i've treid the following :

$(".news").on("click","news",popUp);
$(".news").on("click",null,"news",popUp);

to call this function with "news" as data:

function popUp (file = "none", opts= {})
{
    alert(file);
}

but this is not working ..

i don't want to send data as object because I'm using this function elsewhere and i don't want to change the function structure.

and can i send string data for file and object data for opts ??

Body:
Your second call to .on() is correct (if the data is a string, you need to pass a null selector, otherwise the data will be assumed to be the selector for a delegated event).

But the data is in event.data in the handler, not a function argument.

$(".news").on("click", null, "news", popUp);

function popUp(event) {
  alert(event.data);
}

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button class="news">Click</button>

If you want to send multiple parameters, use an object.

$(".news").on("click", {
  file: "news",
  options: {
    something: "blah blah"
  }
}, popUp);

function popUp(event) {
  if (event.data) {
    let {
      file: file,
      options: opt
    } = event.data;
    alert(file + " " + opt.something);
  }
}

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button class="news">Click</button>


问:
Why is my Lambda callback not working?
I am running a AWS Cognito signin process authentication API on AWS SAM local. I am getting authed correctly from Cognito but when the signInUser promise resolves (with the correct response), instead of the callback with the statusCode of 200 getting fired, it fires the callback in the catch (with the statusCode of 400).

See Lambda function here:-

```<code>// A signin Lambda function
export function handler (event: Object, context: Object, callback: Function) {
    switch (event.httpMethod) {
        case "GET":
            // hard code login for SO question
            signInUser({ username: 'XXXX', password: 'XXXXXXX'})
                .then((response) => {
                    console.log('This log is called correctly but callback on the next line is not');
                    callback(null, {
                        statusCode: 200,
                        header: response.tokens.idToken.jwtToken,
                        body: "This is a signin operation, return success result"
                    });
                 })
                .catch(
                    callback(null, {
                        statusCode: 400,
                        body: "This is a failed signin operation"
                    })
                );
            break;
        default:
            // Send HTTP 501: Not Implemented
            console.log("Error: unsupported HTTP method (" + event.httpMethod + ")");
            callback(null, {statusCode: 501})

    }
}
</code>```

Any ideas what is causing this to happen or how to fix it?

Much thanks!

答:
.catch() takes a function, but you are passing it the result of your callback. Try this:

```<code>.catch( (error) =>
    callback(null, {
        statusCode: 400,
        body: "This is a failed signin operation"
    })
)
</code>```

Title: Why is my Lambda callback not working?

Body:
I am running a AWS Cognito signin process authentication API on AWS SAM local. I am getting authed correctly from Cognito but when the signInUser promise resolves (with the correct response), instead of the callback with the statusCode of 200 getting fired, it fires the callback in the catch (with the statusCode of 400).

See Lambda function here:-

// A signin Lambda function
export function handler (event: Object, context: Object, callback: Function) {
    switch (event.httpMethod) {
        case "GET":
            // hard code login for SO question
            signInUser({ username: 'XXXX', password: 'XXXXXXX'})
                .then((response) => {
                    console.log('This log is called correctly but callback on the next line is not');
                    callback(null, {
                        statusCode: 200,
                        header: response.tokens.idToken.jwtToken,
                        body: "This is a signin operation, return success result"
                    });
                 })
                .catch(
                    callback(null, {
                        statusCode: 400,
                        body: "This is a failed signin operation"
                    })
                );
            break;
        default:
            // Send HTTP 501: Not Implemented
            console.log("Error: unsupported HTTP method (" + event.httpMethod + ")");
            callback(null, {statusCode: 501})

    }
}

Any ideas what is causing this to happen or how to fix it?

Much thanks!

Body:
.catch() takes a function, but you are passing it the result of your callback. Try this:

.catch( (error) =>
    callback(null, {
        statusCode: 400,
        body: "This is a failed signin operation"
    })
)


问:
add one more source to the repo manifest
I need to build an image for a Xilinx FPGA. Followed these directions. Everything worked and I managed to build it. Now I need to add an extra layer. I thought all I needed to do is to modify .repo/manifests/default.xml (add this layer, https://github.com/sbabic/meta-swupdate/tree/rocko) and then execute

repo sync

but I'm getting errors saying that changes to multitude of files will be overwritten by a checkout (these are the files that were built).

So how do I add a layer to my current environment and rebuild with a new layer without actually rebuilding the whole thing?

答:
```<code>cd ./sources/
git clone https://github.com/sbabic/meta-swupdate.git
cd ../conf/
vi ./bblayers.conf
add **{BSPDIR}/sources/meta-swupdate \** before (")
vi ./local.conf
add **IMAGE_INSTALL_append = " swupdate" **
bitbake
</code>```

How to add Layer example: https://www.youtube.com/watch?v=3HsaoVqX7dg

Body:
cd ./sources/
git clone https://github.com/sbabic/meta-swupdate.git
cd ../conf/
vi ./bblayers.conf
add **{BSPDIR}/sources/meta-swupdate \** before (")
vi ./local.conf
add **IMAGE_INSTALL_append = " swupdate" **
bitbake

How to add Layer example: https://www.youtube.com/watch?v=3HsaoVqX7dg


问:
Haskell Matrix equality failing
I'm messing around with using Haskell for implementing some quantum transformation matrices. I have a function designed to test if a square matrix is unitary or not by building the inverse and adjoint matrices and then testing both.

The function is shown below, where wrap is a simple function used to test the Either value returned from inverse.

```<code>isUnitary :: [[Copmlex Double]] -> Bool
isUnitary lists = let mat =  fromLists lists --Create matrix from lists
                      conjugateTranspose = fmap conjugate $ Data.Matrix.transpose mat --Conjugate Transpose Matrix
                      inverseMat = debug("ConjugateTranspose: \n" ++ show conjugateTranspose ++ "\n")
                                    wrap $ inverse mat --The inverse matrix
                      in if (conjugateTranspose) == inverseMat then debug("InverseMat: \n" ++ show inverseMat ++ "\n")
                                                                      True
                         else debug("InverseMat: \n" ++ show inverseMat ++ "\n")
                                False
</code>```

For some simple test matrices it works fine, returning True when getting the matrices shown below:

```<code>ConjugateTranspose:
(    1.0 :+ (-0.0)                   0.0 :+ (-0.0) )
(    0.0 :+ (-0.0)                   (-1.0) :+ (-0.0) )

InverseMat:
(    1.0 :+ 0.0                      0.0 :+ 0.0 )
(    0.0 :+ (-0.0)                   (-1.0) :+ (-0.0) )
</code>```

My problem is that the function returns False for the Hadamard transform matrix built by using ((1/sqrt(2) :+ 0) and ((-1/sqrt(2)) :+ 0))

```<code>ConjugateTranspose:
(    0.7071067811865475 :+ (-0.0)    0.7071067811865475 :+ (-0.0) )
(    0.7071067811865475 :+ (-0.0)    (-0.7071067811865475) :+ (-0.0) )

InverseMat:
(    0.7071067811865476 :+ 0.0       0.7071067811865476 :+ 0.0 )
(    0.7071067811865476 :+ 0.0       (-0.7071067811865476) :+ (-0.0) )
</code>```

What could be causing the equality test for the second pair of matrices to fail? Is there a more correct way for me to present the complex numbers in the code?

答:
Double are floating point numbers, and floating point numbers are inherently inaccurate. == is going to perform an exact equality check, where you likely want a "close enough" equality check.

Alternatively, you can use a different numeric type that either 1) has fixed precision (like , or 2) unbounded memory use for unlimited precision. scientific is a good choice, as is fixed.

Title: Haskell Matrix equality failing

Body:
I'm messing around with using Haskell for implementing some quantum transformation matrices. I have a function designed to test if a square matrix is unitary or not by building the inverse and adjoint matrices and then testing both.

The function is shown below, where wrap is a simple function used to test the Either value returned from inverse.

isUnitary :: [[Copmlex Double]] -> Bool
isUnitary lists = let mat =  fromLists lists --Create matrix from lists
                      conjugateTranspose = fmap conjugate $ Data.Matrix.transpose mat --Conjugate Transpose Matrix
                      inverseMat = debug("ConjugateTranspose: \n" ++ show conjugateTranspose ++ "\n")
                                    wrap $ inverse mat --The inverse matrix
                      in if (conjugateTranspose) == inverseMat then debug("InverseMat: \n" ++ show inverseMat ++ "\n")
                                                                      True
                         else debug("InverseMat: \n" ++ show inverseMat ++ "\n")
                                False

For some simple test matrices it works fine, returning True when getting the matrices shown below:

ConjugateTranspose:
(    1.0 :+ (-0.0)                   0.0 :+ (-0.0) )
(    0.0 :+ (-0.0)                   (-1.0) :+ (-0.0) )

InverseMat:
(    1.0 :+ 0.0                      0.0 :+ 0.0 )
(    0.0 :+ (-0.0)                   (-1.0) :+ (-0.0) )

My problem is that the function returns False for the Hadamard transform matrix built by using ((1/sqrt(2) :+ 0) and ((-1/sqrt(2)) :+ 0))

ConjugateTranspose:
(    0.7071067811865475 :+ (-0.0)    0.7071067811865475 :+ (-0.0) )
(    0.7071067811865475 :+ (-0.0)    (-0.7071067811865475) :+ (-0.0) )

InverseMat:
(    0.7071067811865476 :+ 0.0       0.7071067811865476 :+ 0.0 )
(    0.7071067811865476 :+ 0.0       (-0.7071067811865476) :+ (-0.0) )

What could be causing the equality test for the second pair of matrices to fail? Is there a more correct way for me to present the complex numbers in the code?


问:
Is it possible to take values of an HTML5 SessionStorage and email it?
I'm creating an application with two pages (Page One, Page Two) that have radio buttons on them. The values are stored in sessionStorage and displayed to the user on Page 3. However, I want a Submit button that will take those values in sessionStorage and email it to me (I was planning to use PHP to process and send the email). Can someone help point me in the right direction on how to solve this please?</p>

答: If you already have a form with your submit button then you could have your javascript insert new inputs of type="hidden", one for each key/value pair. These values will then be submitted with the form so you can process them just like any other POST parameter.