Skip to content

Commit

Permalink
#598: RPC method handle is asm+path+signature hash
Browse files Browse the repository at this point in the history
  • Loading branch information
Jand42 committed Aug 28, 2016
1 parent 4feb95d commit d260127
Show file tree
Hide file tree
Showing 5 changed files with 33 additions and 16 deletions.
12 changes: 9 additions & 3 deletions src/compiler/WebSharper.Compiler.CSharp/ProjectReader.fs
Original file line number Diff line number Diff line change
Expand Up @@ -280,8 +280,8 @@ let private transformClass (rcomp: CSharpCompilation) (sr: R.SymbolReader) (comp
| Member.Override(_, _) -> error "Override method can't have Stub attribute"
| Member.StaticConstructor -> error "Static constructor can't have Stub attribute"
| Some (A.MemberKind.Remote rp) ->
let def = sr.ReadMember meth
match def with
let memdef = sr.ReadMember meth
match memdef with
| Member.Method (isInstance, mdef) ->
let remotingKind =
match mdef.Value.ReturnType with
Expand All @@ -291,7 +291,13 @@ let private transformClass (rcomp: CSharpCompilation) (sr: R.SymbolReader) (comp
| _ -> RemoteSync // TODO: warning
let isCsrfProtected t = true // TODO
let rp = rp |> Option.map (fun t -> t, isCsrfProtected t)
addMethod mAnnot mdef (N.Remote(remotingKind, comp.GetRemoteHandle(), rp)) true Undefined
let handle =
comp.GetRemoteHandle(
def.Value.FullName + "." + mdef.Value.MethodName,
mdef.Value.Parameters,
mdef.Value.ReturnType
)
addMethod mAnnot mdef (N.Remote(remotingKind, handle, rp)) true Undefined
| _ -> error "Only methods can be defined Remote"
| Some kind ->
let meth =
Expand Down
8 changes: 7 additions & 1 deletion src/compiler/WebSharper.Compiler.FSharp/ProjectReader.fs
Original file line number Diff line number Diff line change
Expand Up @@ -261,7 +261,13 @@ let rec private transformClass (sc: Lazy<_ * StartupCode>) (comp: Compilation) (
| _ -> RemoteSync
let isCsrfProtected t = true // TODO
let rp = rp |> Option.map (fun t -> t, isCsrfProtected t)
addMethod (Some (meth, memdef)) mAnnot mdef (N.Remote(remotingKind, comp.GetRemoteHandle(), rp)) true Undefined
let handle =
comp.GetRemoteHandle(
def.Value.FullName + "." + mdef.Value.MethodName,
mdef.Value.Parameters,
mdef.Value.ReturnType
)
addMethod (Some (meth, memdef)) mAnnot mdef (N.Remote(remotingKind, handle, rp)) true Undefined
| _ -> error "Only methods can be defined Remote"
| _ -> ()

Expand Down
7 changes: 3 additions & 4 deletions src/compiler/WebSharper.Compiler/Compilation.fs
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,6 @@ type Compilation(meta: Info, ?hasGraph) =
let warnings = ResizeArray()

let mutable entryPoint = None
let mutable remotingCode = -1

let macros = System.Collections.Generic.Dictionary<TypeDefinition, Macro option>()
let generators = System.Collections.Generic.Dictionary<TypeDefinition, Generator option>()
Expand All @@ -73,11 +72,11 @@ type Compilation(meta: Info, ?hasGraph) =
| Some p -> p
| _ -> typ

member this.GetRemoteHandle() =
remotingCode <- remotingCode + 1
member this.GetRemoteHandle(path: string, args: Type list, ret: Type) =
{
Assembly = this.AssemblyName
Code = remotingCode
Path = path
SignatureHash = hash (args, ret)
}

member this.AddError (pos : SourcePos option, error : CompilationError) =
Expand Down
11 changes: 5 additions & 6 deletions src/compiler/WebSharper.Core/Metadata.fs
Original file line number Diff line number Diff line change
Expand Up @@ -35,17 +35,16 @@ type RemotingKind =
type MethodHandle =
{
Assembly : string
Code : int
Path : string
SignatureHash : int
}
member this.Pack() =
string this.Assembly + ":" + string this.Code
this.Assembly + ":" + this.Path + ":" + string this.SignatureHash

static member Unpack(s: string) =
try
let i = s.LastIndexOf ':'
let code = int (s.Substring(i + 1))
let assembly = s.Substring(0, i)
{ Assembly = assembly; Code = code }
let p = s.Split(':')
{ Assembly = p.[0]; Path = p.[1]; SignatureHash = int p.[2] }
with _ ->
failwith "Failed to deserialize method handle"

Expand Down
11 changes: 9 additions & 2 deletions src/compiler/WebSharper.Core/Remoting.fs
Original file line number Diff line number Diff line change
Expand Up @@ -179,15 +179,22 @@ let IsRemotingRequest (h: Headers) =
| _ -> false

exception InvalidHeadersException
exception NoRemoteAttributeException
exception RemotingException of message: string with
override this.Message = this.message

[<Sealed>]
type Server(info, jP) =
let remote = M.Utilities.getRemoteMethods info
let withoutHash =
remote.Keys |> Seq.map (fun h -> h.Assembly, h.Path) |> HashSet
let d = ConcurrentDictionary()
let getConverter m =
match remote.TryFind m with
| None -> raise NoRemoteAttributeException
| None ->
if withoutHash.Contains (m.Assembly, m.Path) then
raise (RemotingException ("Remote method signature incompatible: " + m.Path + ", " + m.Assembly))
else
raise (RemotingException ("Remote method not found: " + m.Path + ", " + m.Assembly))
| Some (td, m) -> toConverter jP (AST.Reflection.LoadMethod td m)
let getCachedConverter m =
d.GetOrAdd(m, valueFactory = Func<_,_>(getConverter))
Expand Down

0 comments on commit d260127

Please sign in to comment.